project_folder = "/Volumes/GoogleDrive/My Drive/Melbourne/UNIMELB/Research/Complexity Project/ICx3_new/Code/behavAnalysis/ICx3_supp/"
code_folder = paste0(project_folder, "Code/")
data_folder = paste0(project_folder, "Data/")

setwd(code_folder)
knitr::opts_knit$set(root.dir = code_folder)

#Import functions
source(file.path(code_folder,"DescriptiveFunctions.R"))

# Participant Data
folderModels = "/Volumes/GoogleDrive/My Drive/Melbourne/UNIMELB/Research/Complexity Project/ICx3_new/Code/behavAnalysis/Output/"

folderOut_figures = paste0(project_folder,"Output/Figures")
folderOut_tables = paste0(project_folder,"Output/Tables")
# Features of the tasks needed for the analysis
SATTaskMaxTime=110
nVars_sat=5
SATTaskMaxClicks = 20

TSPTaskMaxTime = 40


# Brms parameters
chains_brms = 4
cores_brms = min(chains_brms,detectCores())
seed_brms = 111
iters_high = 4000
## Setting up the basics
library(ggplot2)
#library(stargazer)
library(knitr)
library(dplyr)
library(ggsignif)
library(pander)
library(plotly)
library(reshape2)
library(Hmisc)
library(readr)
library(brms)
library(parallel)
library(sjstats)
library(bayesplot)
library(bmlm)
library(DiagrammeR)
library(tidyr)

#From easystats:
library(parameters)
library(see)
library(bayestestR)
library(performance)

library(forcats)
library(ggpol)
# Functions

save_summarise_model = function(model, modelName){
  if (modelName %in% names(allModels)){
    warning("Model Name already exists!")
    model = allModels[[modelName]]
  } else {
    allModels[[modelName]]<<- model
  }
    table = model_parameters(model, 
                              ci_method = "HDI",ci=0.95,test = c("hdi","pd"))
    
    table2 = performance::model_performance(model,metrics="common")

    plo = plot(hdi(model, ci = c(0.95)), data = model)+
          ggtitle("Posterior distributions",
                  "with medians and 95% quantile-based-intervals") +
          theme(plot.title = element_text(hjust = 0.5),
                plot.subtitle = element_text(hjust = 0.5))
  
    print(as_tibble(table))
    print(as_tibble(table2))
    print(plo)
  
    #allModels[[modelName]]<<- model
}
# Use current models or rerun everything Comment one option

# allModels := list of all the regressions that are run 


## Option1: Use current saved models

# Import estimated models
allModels = read_rds(file.path(folderModels,"ICx3_models.RData"))

# Don't run brms models
brm2 =  function(...){
  return(FALSE)
}

# ## Option2: Rerun everything from scratch
# 
# allModels=vector("list", length=0)
# 
# brm2 =  function(...){
#   return(brm(...))
# }

1 Boolean satisfiability problem (3SAT)

1.1 Functions

calculate_sat_ICexpost =function(min_cost,nclauses){
  ICexpost  =  min_cost/nclauses
  return(ICexpost)
}

1.2 Accuracy

Read Clean Data to file

#Import SAT data
dataTrial_SAT= read_csv2(file.path(data_folder,"SAT_clean.csv"))
Using ',' as decimal and '.' as grouping mark. Use read_delim() for more control.
Parsed with column specification:
cols(
  .default = col_double(),
  pID = col_character(),
  error = col_logical(),
  v = col_character(),
  l = col_character(),
  id = col_character(),
  region = col_character()
)
See spec(...) for full column specifications.
dataTrial_SAT_Time = read_csv2(file.path(data_folder,"SAT_clean_time.csv"))
Using ',' as decimal and '.' as grouping mark. Use read_delim() for more control.
Parsed with column specification:
cols(
  .default = col_double(),
  pID = col_character(),
  error = col_logical(),
  v = col_character(),
  l = col_character(),
  id = col_character(),
  region = col_character()
)
See spec(...) for full column specifications.
dataTrial_SAT_Time$timeSpent_pct = dataTrial_SAT_Time$timeSpent/SATTaskMaxTime

color_scheme_set("green")

dataTrial_SAT$censored_time = ifelse(dataTrial_SAT$timeSpent == SATTaskMaxTime,
                             "right","none")

dataTrial_SAT_Time$censored_time = ifelse(dataTrial_SAT_Time$timeSpent == SATTaskMaxTime,
                             "right","none")

instanceProperties_SAT= read_rds(paste0(data_folder,"instance_properties_SAT.rds"))
instanceProperties_SAT = instanceProperties_SAT %>% select(instanceNumber, min_cost, min_model,costs,models,nSolutions)

dataTrial_SAT = left_join(dataTrial_SAT,instanceProperties_SAT, by = "instanceNumber")
dataTrial_SAT_Time = left_join(dataTrial_SAT_Time,instanceProperties_SAT, by = "instanceNumber")

dataTrial_SAT$ICexpost = calculate_sat_ICexpost(dataTrial_SAT$min_cost,dataTrial_SAT$nClauses)
dataTrial_SAT_Time$ICexpost = calculate_sat_ICexpost(dataTrial_SAT_Time$min_cost,dataTrial_SAT_Time$nClauses)

#CLicks
data_SAT_clicks = read_csv2(file.path(data_folder,"SAT_clicks.csv"))
Using ',' as decimal and '.' as grouping mark. Use read_delim() for more control.
Parsed with column specification:
cols(
  pID = col_character(),
  block = col_double(),
  trial = col_double(),
  clicknumber = col_double(),
  Variable = col_double(),
  Literal = col_double(),
  state = col_double(),
  time = col_double()
)
nClicks = data_SAT_clicks %>% group_by(pID,block,trial) %>% summarise(n_clicks =n())
`summarise()` regrouping output by 'pID', 'block' (override with `.groups` argument)
dataTrial_SAT_clicks=merge(nClicks,
                  dataTrial_SAT, by=c("pID","block","trial"))

dataTrial_SAT_clicks$censored_clicks = ifelse(dataTrial_SAT_clicks$n_clicks== SATTaskMaxClicks,
                             "right","none")
#Summary Stats for Decision Problem
dataInput=dataTrial_SAT

accuracySummary = dataInput %>% group_by(pID) %>% summarise(acc=mean(correct)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))

summarise() ungrouping output (override with .groups argument)

kable(accuracySummary, digits=2, caption = "Accuracy Summary")

Accuracy Summary
mean min max SD
0.87 0.75 0.98 0.06


answerSummary = dataInput %>% group_by(pID) %>% summarise(acc=mean(answer)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))

summarise() ungrouping output (override with .groups argument)

kable(answerSummary, digits=2, caption = "Proportion of times that YES was selected as the answer")

Proportion of times that YES was selected as the answer
mean min max SD
0.45 0.28 0.61 0.09


yesNoProportions = dataInput %>% group_by(sol,pID) %>% summarise(acc=mean(correct)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))

summarise() regrouping output by ‘sol’ (override with .groups argument) summarise() ungrouping output (override with .groups argument)

kable(yesNoProportions, digits=2, caption = "Accuracy By Solution")

Accuracy By Solution
sol mean min max SD
0 0.94 0.74 1 0.08
1 0.81 0.55 1 0.13

NA

1.2.1 Effect of Trial number on accuracy

#Trial (experience effect) effect
dataInput=dataTrial_SAT

#Summary
summaryByBlock = dataInput %>% group_by(block,pID) %>% summarise(acc=mean(correct)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))
`summarise()` regrouping output by 'block' (override with `.groups` argument)
`summarise()` ungrouping output (override with `.groups` argument)
kable(summaryByBlock, digits=2, caption = "Accuracy By Block Number")

Accuracy By Block Number
block mean min max SD
1 0.85 0.75 1 0.07
2 0.87 0.69 1 0.08
3 0.88 0.69 1 0.09
4 0.87 0.69 1 0.10


#Regresssion
dataInput$totalTrial = dataInput$block * dataInput$trial

logitRandomIntercept = brm2(correct ~ totalTrial+ (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput, chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms, refresh = 0)

tableName='sat_acc_01_r'

save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

1.2.2 TCC Accuracy Contrast

dataInput=dataTrial_SAT %>% group_by(phaseT,pID)%>%summarise(accuracy1=mean(correct))%>%ungroup()%>%group_by(phaseT)%>%summarise(accuracy=mean(accuracy1),se=se(accuracy1))%>%ungroup()
`summarise()` regrouping output by 'phaseT' (override with `.groups` argument)
`summarise()` ungrouping output (override with `.groups` argument)
dataInput$phaseT = recode(dataInput$phaseT, '0' = "Low IC", '1' = "High IC")

plo= ggplot(data=dataInput, aes(y=accuracy, x=as.factor(phaseT),label = round(accuracy,digits = 2))) +
  geom_bar(stat = "identity")+
  geom_errorbar(aes(ymin=accuracy-se, ymax=accuracy+se), width=.1)+
  #geom_signif(comparisons = list(c("Low IC","High IC")), annotations="***", y_position = 0.95, tip_length = 0.03)+
  labs(title="Accuracy In and Out of phase Transition",x="Instance complexity",y="Accuracy")+
  coord_cartesian(ylim = c(0.5,1))+
  geom_text(hjust=0.5,vjust = 5, colour="white")+
  theme_light()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),plot.title = element_text(hjust = 0.5))

outputName = 'sat_acc_02_g'
plotExport(plo,outputName,folderOut_figures)
[1] "sat_acc_02_g"
quartz_off_screen 
                2 

#Logistic Regression for In/Out Phase transition
dataInput= dataTrial_SAT

#logistic with random effects (intercept)
logitRandomIntercept = brm2(correct ~ phaseT + (1|pID),
                           family=bernoulli(link="logit"),#binomial(link="logit"),
                           data=dataInput, 
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0)


tableName='sat_acc_02_r'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

1.2.2.1 Plot TCC

dataInput = dataTrial_SAT
dataInput = dataInput %>% 
  mutate(region = fct_relevel(region,
                              "Underconstrained", "Phase Transition", "Overconstrained"))%>% 
  mutate(sol= as.factor(sol)) %>% 
  mutate(sol = fct_relevel(sol,"1", "0"))

dataInput2 = dataInput %>% 
  group_by(instanceNumber,region,sol) %>% 
  summarise(accuracy=mean(correct))
`summarise()` regrouping output by 'instanceNumber', 'region' (override with `.groups` argument)
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7


plo = ggplot(dataInput2,aes(x=region,y=accuracy,fill=sol))+
  # geom_boxjitter(aes(fill=region),jitter.color = NA,jitter.shape = 21)+
  geom_boxjitter(jitter.color = NA,jitter.shape = 21,
                 jitter.params = list(height=0,seed=10),
                 outlier.shape= NA)+
                 #,outlier.shape = 4, outlier.size=0.9)+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0.5))+
  scale_fill_manual(name  ="Region",
                    breaks=c("1","0"),
                    labels=c("Satisfiable","Unsatisfiable"),
                    values=c("#90BE6D","#F94144"))+
  xlab("Typical Case Complexity (TCC)")+
  ylab("Human Performance")+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))+
  ylim(0.2,1)


plo
ggsave(paste0(folderOut_figures,"/TCC_SAT_acc.pdf"),plo,width = 7,height =6,units="in")

#brewer

1.2.3 Satisifability and TCC


dataInput=dataTrial_SAT %>% group_by(phaseT,sol,pID)%>%summarise(accuracy1=mean(correct))%>%ungroup()%>%group_by(sol,phaseT)%>%summarise(accuracy=mean(accuracy1),se=se(accuracy1))%>%ungroup()
`summarise()` regrouping output by 'phaseT', 'sol' (override with `.groups` argument)
`summarise()` regrouping output by 'sol' (override with `.groups` argument)
sol_names <- c(
                    `0` = "Correct answer: NO",
                    `1` = "Correct answer: YES",
                    `2` = "If this is here it means data not filtered"
                    )

plo=ggplot(data=dataInput, aes(y=accuracy, x=as.factor(as.logical(phaseT)), label = round(accuracy,digits = 2),group=1)) +
  geom_line()+
  geom_errorbar(aes(ymin=accuracy-se, ymax=accuracy+se), width=.1) +
  geom_point(shape=21, size=3, fill="white")+
  labs(title="Accuracy segregated by solvability",x="In Phase Transition?",y="Accuracy")+
  theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(angle=0,hjust=0.5))+
  geom_text(hjust=-0.5, colour="black")+
  facet_grid(.~sol, labeller = as_labeller(sol_names))

outputName = 'sat_acc_03_g'
plotExport(plo,outputName,folderOut_figures)
[1] "sat_acc_03_g"
quartz_off_screen 
                2 

dataInput= dataTrial_SAT
dataInput$phaseT = as.factor(dataInput$phaseT)
dataInput$sol = as.factor(dataInput$sol)
#logistic with random effects (intercept)
logitRandomIntercept = brm2(correct ~ phaseT + sol + phaseT:sol + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput, 
                           chains=chains_brms,
                           cores = cores_brms,                            seed=seed_brms,                            refresh = 0)

tableName='sat_acc_03_r'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

Marginal effects


#marginal_effects(logitRandomIntercept, ask=FALSE)
plot(marginal_effects(allModels[['sat_acc_03_r']]), plot = TRUE, ask = FALSE)
Method 'marginal_effects' is deprecated. Please use 'conditional_effects' instead.

Effect of TCC on satisfiable instances

# st01
model = allModels[['sat_acc_03_r']]

fit = hypothesis(model,"phaseT1+ phaseT1:sol1=0", seed=seed_brms)

print(fit)
Hypothesis Tests for class b:
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
hdi(fit$samples,ci=0.95)
# Highest Density Interval

Parameter |        95% HDI
--------------------------
H1        | [-2.53, -1.56]

1.2.3.1 Satisfiability alone

dataInput= dataTrial_SAT
dataInput$sol = as.factor(dataInput$sol)
#logistic with random effects (intercept)
logitRandomIntercept = brm2(correct ~ sol + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput, 
                           chains=chains_brms,
                           cores = cores_brms,                            seed=seed_brms,                            refresh = 0)

tableName='sat_acc_03B_r'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

1.2.4 Region effect on Accuracy

Overconstrained - Underconstrained - Satisfiability threshold

dataInput=dataTrial_SAT

# dataInput$pID=as.character(dataInput$pID)
# ps = sample(pull(dataInput,pID),20)
# dataInput = dataInput %>% filter(pID %in% ps)


dataInput2=dataInput %>% group_by(region,pID)%>%summarise(accuracy1=mean(correct))%>%
  ungroup()%>%group_by(region)%>%summarise(accuracy=mean(accuracy1),se=se(accuracy1))%>%ungroup()
`summarise()` regrouping output by 'region' (override with `.groups` argument)
`summarise()` ungrouping output (override with `.groups` argument)
dataInput2$region <- factor(dataInput2$region, levels = c('Underconstrained',
                                                          'Phase Transition',
                                                          'Overconstrained'))

plo= ggplot(data=dataInput2, aes(y=accuracy, x=region, label = round(accuracy,digits = 2))) +
  geom_bar(stat = "identity")+
  geom_errorbar(aes(ymin=accuracy-se, ymax=accuracy+se), width=.1)+
  labs(title="Accuracy by region",x="Region",y="Accuracy")+
  coord_cartesian(ylim = c(0.5,1))+
  geom_text(hjust=0.5,vjust = 5, colour="white") +
  theme_light()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),plot.title = element_text(hjust = 0.5))

outputName = 'sat_acc_04_g'
plotExport(plo,outputName,folderOut_figures)
[1] "sat_acc_04_g"
quartz_off_screen 
                2 

#Stats test for time in and out of phase transition: ANOVA
dataInput$overConstrained= (dataInput$region=='Overconstrained')
dataInput$underConstrained= (dataInput$region=='Underconstrained')

logitRandomIntercept = brm2(correct ~ overConstrained + underConstrained + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput, 
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms, refresh = 0)

tableName='sat_acc_04_r_A'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

Is there a difference between accuracy in the overconstrained region and the underconstrained region?


fit = hypothesis(allModels[['sat_acc_04_r_A']],"overConstrainedTRUE=underConstrainedTRUE", seed=seed_brms)

print(fit)
Hypothesis Tests for class b:
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
hdi(fit$samples,ci=0.95)
# Highest Density Interval

Parameter |       95% HDI
-------------------------
H1        | [-1.15, 0.24]

Region Effect on Accuracy by region and Satisfiability

dataInput=dataTrial_SAT 

# dataInput$pID=as.character(dataInput$pID)
# ps = sample(pull(dataInput,pID),20)
# dataInput = dataInput %>% filter(pID %in% ps)

dataInput2=dataInput %>% group_by(region,pID,sol)%>%summarise(accuracy1=mean(correct))%>%ungroup()%>%group_by(region,sol)%>%summarise(accuracy=mean(accuracy1),se=se(accuracy1))%>%ungroup()
`summarise()` regrouping output by 'region', 'pID' (override with `.groups` argument)
`summarise()` regrouping output by 'region' (override with `.groups` argument)
dataInput2$region <- factor(dataInput2$region, levels = c('Underconstrained',
                                                          'Phase Transition',
                                                          'Overconstrained'))

dataInput2$sol = recode(dataInput2$sol, '1' = "Solvable", '0' = "Non-Solvable")

plo= ggplot(data=dataInput2, aes(y=accuracy, x=region, label = round(accuracy,digits = 2))) +
  geom_bar(stat = "identity")+
  #geom_signif(annotations = c("***","***"),
  #            y_position=c(0.95,0.95),xmin=c(1.1,2.1),xmax=c(1.9,2.9))+
  #geom_signif(comparisons = list(c("Underconstrained","Overconstrained")),
  #             annotations="NS", y_position = 0.99, tip_length = 0.03)+
  geom_errorbar(aes(ymin=accuracy-se, ymax=accuracy+se), width=.1)+
  labs(title="Accuracy by region",x="Region",y="Accuracy")+
  coord_cartesian(ylim = c(0.5,1))+
  geom_text(hjust=0.5,vjust = 5, colour="white") +
  theme_light()+
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(),plot.title = element_text(hjust = 0.5))+
  facet_grid(.~sol)


outputName = 'sat_acc_04_g'
plotExport(plo,outputName,folderOut_figures)
[1] "sat_acc_04_g"
quartz_off_screen 
                2 

#Stats test for time in and out of phase transition: ANOVA
dataInput$overConstrained= (dataInput$region=='Overconstrained')
dataInput$underConstrained= (dataInput$region=='Underconstrained')

1.2.5 Number of solutions witnesses that satisfy the constraints

dataInput=dataTrial_SAT
#dataInput=nSolutions_sat(dataInput)

#Plots nSolutions (x) vs. Accuracy (y)
dataInput3 = dataInput %>% group_by(nSolutions,pID,phaseT)%>%summarise(accuracyMeans=mean(correct))%>%ungroup()%>%group_by(nSolutions,phaseT)%>%summarise(accuracy=mean(accuracyMeans),se=se(accuracyMeans))%>%ungroup()
`summarise()` regrouping output by 'nSolutions', 'pID' (override with `.groups` argument)
`summarise()` regrouping output by 'nSolutions' (override with `.groups` argument)
dataInput3$sol = dataInput3$nSolutions>=1
dataInput3$phaseT = recode(dataInput3$phaseT, '0' = "Low IC", '1' = "High IC")

plo= ggplot(data=dataInput3, aes(y=accuracy, x=as.factor(nSolutions))) +
  geom_errorbar(aes(ymin=accuracy-se, ymax=accuracy+se), width=.1)+
  geom_point(shape=23, size=3, fill="red")+
  labs(title="Accuracy and the Number of Solutions",
       x="Number of   Solutions",y="Accuracy")+
  coord_cartesian(ylim = c(0.5,1))+
  theme_light()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0.5),strip.text.x = element_blank())+
  facet_grid(phaseT~sol, scales = "free_x", space = "free_x")+
  geom_smooth(data=dataInput3, aes(y=accuracy, x=nSolutions),method=glm,se=FALSE,fullrange=TRUE,linetype = "dashed")

outputName = 'sat_acc_05_g'
plotExport(plo,outputName,folderOut_figures)
[1] "sat_acc_05_g"
quartz_off_screen 
                2 

Difference in the number of solutions of instances High/Low TCC (clearly, only for solvable instances)


dataInput2 = unique(dataInput %>% select(phaseT,id,nSolutions,sol) %>% filter(sol==1))
diffMeans = t.test(nSolutions ~ phaseT ,data=dataInput2)
pander(diffMeans)

-------------------------------------------------------------------
 Test statistic    df         P value       Alternative hypothesis 
---------------- ------- ----------------- ------------------------
     8.961        18.22   4.244e-08 * * *         two.sided        
-------------------------------------------------------------------

Table: Welch Two Sample t-test: `nSolutions` by `phaseT` (continued below)

 
-----------------------------------
 mean in group 0   mean in group 1 
----------------- -----------------
      6.588             1.312      
-----------------------------------

Regression for the number of witnesses analysis: correct ~ sol + phaseT + nSolutions + phaseT:nSolutions + (1|pID)

dataInput = dataInput %>% filter(sol==1)

#Includes a dummy if nSolutions==0, that's variable: sol.
logitRandomIntercept = brm2(correct ~ phaseT + nSolutions + phaseT:nSolutions + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput, 
                           chains=chains_brms,
                           cores = cores_brms,                            seed=seed_brms, refresh = 0)

tableName='sat_acc_05_r_A'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

This calculates the significance of the beta(slope) of the numberOfSolutions for high TCC instances.

#This version recodes phaseT to OutphaseT, to 

fit = hypothesis(allModels[['sat_acc_05_r_A']],"nSolutions + phaseT:nSolutions = 0", seed=seed_brms)

print(fit)
Hypothesis Tests for class b:
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
hdi(fit$samples,ci=0.95)
# Highest Density Interval

Parameter |      95% HDI
------------------------
H1        | [0.64, 1.79]

Marginal Effects


plot(marginal_effects(allModels[['sat_acc_05_r_A']]), plot = TRUE, ask = FALSE)
Method 'marginal_effects' is deprecated. Please use 'conditional_effects' instead.

1.2.5.1 NSol (regressed alone)

#st02
dataInput = dataTrial_SAT
dataInput = dataInput %>% filter(sol==1)

#Includes a dummy if nSolutions==0, that's variable: sol.
logitRandomIntercept = brm2(correct ~ nSolutions + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput, 
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms, refresh = 0)

tableName='sat_acc_05_r_B'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

mean_acc = dataInput %>% group_by(instanceNumber,nSolutions, sol,phaseT) %>%
  summarise(accuracy=mean(correct)) 
`summarise()` regrouping output by 'instanceNumber', 'nSolutions', 'sol' (override with `.groups` argument)
logitRandomIntercept = allModels[['sat_acc_05_r_B']]
pp  = plot(conditional_effects(logitRandomIntercept), plot = FALSE, ask = FALSE)

pp$nSolutions + 
  geom_point(data=mean_acc,aes(x = nSolutions, y = accuracy),inherit.aes = FALSE)

# Improving the plot
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

pp_plot = pp$nSolutions
pp_plot$layers[[1]]$geom_params$se = FALSE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_point(data=mean_acc,
                               aes(x = nSolutions, y = accuracy, col=as.factor(sol),
                                   shape=as.factor(phaseT), size=2.5), inherit.aes = FALSE),
                         pp_plot$layers)


plo = pp_plot +
  xlab("Number of solution Witnesses")+#expression(IC[expost]))+
  ylab("Human Performance")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  scale_x_continuous(breaks = c(1,3,5,7,9),limits =c(1,10))+
  guides(shape = guide_legend(override.aes = list(size = 3)))+
  ylim(0.2,1)


plo
ggsave(paste0(folderOut_figures,"/Nwit_SAT_acc.pdf"),plo,width = 6,height =6,units="in")

1.2.5.2 NSol (with TCC and no interaction)

#st03
dataInput = dataTrial_SAT
dataInput = dataInput %>% filter(sol==1)

logitRandomIntercept = brm2(correct ~ nSolutions + phaseT + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput, 
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms, refresh = 0)

tableName='sat_acc_05_r_C'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

1.2.6 IC_expost

dataInput = dataTrial_SAT

# Summarise the data to plot
mean_accuracy = dataInput %>% 
  group_by(instanceNumber, sol, ICexpost, phaseT, nSolutions) %>% 
  summarise(accuracy = mean(correct))
`summarise()` regrouping output by 'instanceNumber', 'sol', 'ICexpost', 'phaseT' (override with `.groups` argument)
ggplot(mean_accuracy, aes(x = ICexpost, y = accuracy))+
  geom_point() +
  theme_light() +
  stat_smooth(formula =  y ~ I(x^0.01), method="lm", se= FALSE)+
  xlab("IC_expost")+
  ylab("Human Accuracy")

dataInput = dataTrial_SAT
model_ICexpost = brm2(correct ~ ICexpost + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0)

tableName='sat_acc_icexpost_all'
save_summarise_model(model_ICexpost, tableName)
Model Name already exists!

mean_accuracy$correct= mean_accuracy$accuracy

model_ICexpost = allModels[['sat_acc_icexpost_all']]
pp  = plot(conditional_effects(model_ICexpost), plot = FALSE, ask = FALSE)

pp$ICexpost + 
  geom_point(data=mean_accuracy,aes(x = ICexpost, y = correct),inherit.aes = FALSE)

# Improving the plot
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

pp_plot = pp$ICexpost
pp_plot$layers[[1]]$geom_params$se = FALSE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_point(data=mean_accuracy,
                               aes(x = ICexpost, y = correct, col=as.factor(sol),
                                   shape=as.factor(phaseT), size=2.5), inherit.aes = FALSE),
                         pp_plot$layers)


plo = pp_plot +
  xlab("Instance Complexity (IC)")+#expression(IC[expost]))+
  ylab("Human Performance")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))+
  ylim(0.2,1)

plo
ggsave(paste0(folderOut_figures,"/IC_SAT_acc.pdf"),plo,width = 6,height =6,units="in")

# Improving the plot
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

plo = pp$ICexpost +
geom_point(data=mean_accuracy,aes(x = ICexpost, y = correct, col=as.factor(phaseT),shape=as.factor(phaseT), size=2.5),inherit.aes = FALSE)+
  xlab("Instance Complexity (IC)")+#expression(IC[expost]))+
  ylab("Human Performance")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c( "#FC4E07","#E7B800"))+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))

plo
ggsave(paste0(folderOut_figures,"/IC_SAT_acc.pdf"),plo,width = 6,height =6,units="in")

Model Fit

model_ICexpost = allModels[['sat_acc_icexpost_all']]
dataInput = dataTrial_SAT

# Make predictions excluding random effects (pID)
predictions = predict(model_ICexpost,dataInput, re_formula = NA)


# Estimating the significance of the fit. This is done considering the probability estimation rather than the binary classification.

#Performs the Hosmer-Lemeshow goodness of fit test
logistic_significance = generalhoslem::logitgof(dataInput$correct, predictions[,1], g = 10, ord = FALSE)
logistic_significance

    Hosmer and Lemeshow test (binary model)

data:  dataInput$correct, predictions[, 1]
X-squared = 16.262, df = 8, p-value = 0.03878
# Finds R2 using binary outcomes
# https://stackoverflow.com/questions/40901445/function-to-calculate-r2-r-squared-in-r
#predictions = predict(model_ICexpost,dataInput, re_formula = NA)
#r_2_binary = cor(dataInput$ICexpost, predictions[,1])^2
r_2_binary = cor(dataInput$correct, predictions[,1])^2
r_2_binary
[1] 0.03659735
# Finds R2 using mean accuracies per instance
predictions2 = predict(model_ICexpost,mean_accuracy, re_formula = NA)
r_2_probabilities = cor(mean_accuracy$accuracy, predictions2[,1])^2
r_2_probabilities
[1] 0.1684351

1.2.6.1 Only unsatisfiable instances

dataInput = dataTrial_SAT
dataInput = dataInput %>% filter(sol==0)
model_ICexpost = brm2(correct ~ ICexpost + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0)

tableName='sat_acc_icexpost'
save_summarise_model(model_ICexpost, tableName)
Model Name already exists!

mean_accuracy2 = dataInput %>% 
  filter(sol == 0) %>% 
  group_by(instanceNumber, sol, ICexpost, phaseT, nSolutions) %>% 
  summarise(accuracy = mean(correct))
`summarise()` regrouping output by 'instanceNumber', 'sol', 'ICexpost', 'phaseT' (override with `.groups` argument)
mean_accuracy2$correct= mean_accuracy2$accuracy

model_ICexpost = allModels[['sat_acc_icexpost']]
pp  = plot(conditional_effects(model_ICexpost), plot = FALSE, ask = FALSE)

pp$ICexpost + 
  geom_point(data=mean_accuracy2,aes(x = ICexpost, y = correct),inherit.aes = FALSE)

Model Fit

model_ICexpost = allModels[['sat_acc_icexpost']]
#st05
dataInput = dataTrial_SAT %>% filter(sol==0)

# Make predictions excluding random effects (pID)
predictions = predict(model_ICexpost,dataInput, re_formula = NA)


# Estimating the significance of the fit. This is done considering the probability estimation rather than the binary classification.

#Performs the Hosmer-Lemeshow goodness of fit test
logistic_significance = generalhoslem::logitgof(dataInput$correct, predictions[,1], g = 10, ord = FALSE)
logistic_significance

    Hosmer and Lemeshow test (binary model)

data:  dataInput$correct, predictions[, 1]
X-squared = 32.849, df = 8, p-value = 6.557e-05
# Finds R2 using binary outcomes
# https://stackoverflow.com/questions/40901445/function-to-calculate-r2-r-squared-in-r
#predictions = predict(model_ICexpost,dataInput, re_formula = NA)
r_2_binary = cor(dataInput$correct, predictions[,1])^2
r_2_binary
[1] 0.0009535048
# Finds R2 using mean accuracies per instance
predictions2 = predict(model_ICexpost,mean_accuracy2, re_formula = NA)
r_2_probabilities = cor(mean_accuracy2$accuracy, predictions2[,1])^2
r_2_probabilities
[1] 0.001720168

1.3 Time Spent

The default data used in this section is dataTrial_SAT_Time. This dataset excludes those participants that never skipped to answer submission.

We first calculate some summary stats for the whole data set (dataTrial_SAT) and see how many participants were excluded in dataTrial_SAT_Time.

1.3.0.1 SummStats SAT

#Summary Stats for Decision Problem
dataInput=dataTrial_SAT

timeSummary = dataInput %>% group_by(pID) %>% summarise(acc=mean(timeSpent)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))

summarise() ungrouping output (override with .groups argument)

kable(timeSummary, digits=1, caption = "Time Summary")

Time Summary
mean min max SD
62.4 15.9 110 21.1


yesNoProportions = dataInput %>% group_by(sol,pID) %>% summarise(acc=mean(timeSpent)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))

summarise() regrouping output by ‘sol’ (override with .groups argument) summarise() ungrouping output (override with .groups argument)

kable(yesNoProportions, digits=1, caption = "Time Spent By Solution")

Time Spent By Solution
sol mean min max SD
0 77.8 16.9 110 24.6
1 48.2 14.9 110 21.4


hist(dataInput$timeSpent,breaks=40)

all_pIDs = unique(dataTrial_SAT$pID)
pIDs_not_in_Time = all_pIDs[!(all_pIDs %in% unique(dataTrial_SAT_Time$pID))]
print(paste0("The participants removed in the TIME df are ", length(pIDs_not_in_Time)))
[1] "The participants removed in the TIME df are 1"
obs_removed = nrow(dataTrial_SAT)-nrow(dataTrial_SAT_Time)
print(paste0("The number of observations removed in the TIME df is ", obs_removed))
[1] "The number of observations removed in the TIME df is 63"

1.3.0.2 SummStats SAT_Time

#Summary Stats for Decision Problem
dataInput=dataTrial_SAT_Time

timeSummary = dataInput %>% group_by(pID) %>% summarise(acc=mean(timeSpent)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))

summarise() ungrouping output (override with .groups argument)

kable(timeSummary, digits=1, caption = "Time Summary")

Time Summary
mean min max SD
60.2 15.9 104.3 18.7


yesNoProportions = dataInput %>% group_by(sol,pID) %>% summarise(acc=mean(timeSpent)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))

summarise() regrouping output by ‘sol’ (override with .groups argument) summarise() ungrouping output (override with .groups argument)

kable(yesNoProportions, digits=1, caption = "Time Spent By Solution")

Time Spent By Solution
sol mean min max SD
0 76.2 16.9 108.7 24.2
1 45.2 14.9 100.2 16.8


hist(dataInput$timeSpent,breaks=40)

1.3.0.3 Effect of Trial Number on Time-on-task

#Trial (experience effect) effect on timeSpent
dataInput=dataTrial_SAT_Time
dataInput$totalTrial = dataInput$block * dataInput$trial

summaryByBlock = dataInput %>% group_by(block,pID) %>% summarise(time=mean(timeSpent)) %>% summarise(mean=mean(time),min=min(time),max=max(time),SD=sd(time))
`summarise()` regrouping output by 'block' (override with `.groups` argument)
`summarise()` ungrouping output (override with `.groups` argument)
kable(summaryByBlock,digits=2 , caption="Time Spent per Trial segregated By Block")

Time Spent per Trial segregated By Block
block mean min max SD
1 71.95 19.38 110.00 21.27
2 63.90 16.81 110.00 19.56
3 55.52 14.69 110.00 22.26
4 49.34 1.68 87.13 21.73


#Regression
linearRandomIntercept = brm2(timeSpent_pct | cens(censored_time) ~ totalTrial,
                            data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms, refresh = 0, iter = iters_high,
                           control = list(adapt_delta = 0.98))

tableName='sat_time_01_r'
save_summarise_model(linearRandomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.

1.3.1 TCC

dataInput=dataTrial_SAT_Time %>% group_by(phaseT,pID)%>%summarise(timeSpent1=mean(timeSpent))%>%ungroup()%>%group_by(phaseT)%>%summarise(timeSpent=mean(timeSpent1),se=se(timeSpent1))%>%ungroup()
`summarise()` regrouping output by 'phaseT' (override with `.groups` argument)
`summarise()` ungrouping output (override with `.groups` argument)
dataInput$phaseT = recode(dataInput$phaseT, '0' = "Low IC", '1' = "High IC")

plo= ggplot(data=dataInput, aes(y=timeSpent, x=as.factor(phaseT),label = round(timeSpent,digits = 1))) +
  geom_bar(stat = "identity")+
  geom_errorbar(aes(ymin=timeSpent-se, ymax=timeSpent+se), width=.1)+
  #geom_signif(comparisons = list(c("Low IC","High IC")), annotations="***", y_position = 0.95, tip_length = 0.03)+
  labs(title="Time Spent In and Out of phase Transition",x="Instance complexity",y="Time Spent")+
  #coord_cartesian(ylim = c(0.5,1))+
  geom_text(hjust=0.5,vjust = 5, colour="white")+
  theme_light()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),plot.title = element_text(hjust = 0.5))

outputName = "sat_time_02_g"
plotExport(plo,outputName,folderOut_figures)
[1] "sat_time_02_g"
quartz_off_screen 
                2 

#Logistic Regression for In/Out Phase transition
dataInput= dataTrial_SAT_Time

#logistic with random effects (intercept)
# TTTODO
randomIntercept = brm2(timeSpent| cens(censored_time) ~ phaseT + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="sat_time_02_r"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

1.3.1.0.1 Plot TCC

dataInput = dataTrial_SAT_Time %>%
  mutate(region = fct_relevel(region,
                              "Underconstrained", "Phase Transition", "Overconstrained")) %>% 
  mutate(sol= as.factor(sol)) %>% 
  mutate(sol = fct_relevel(sol,"1", "0"))

dataInput$timeSpent_pct = dataInput$timeSpent/SATTaskMaxTime
dataInput2 = dataInput %>% 
  group_by(instanceNumber,region,sol, phaseT) %>% 
  summarise(timeSpent_pct=median(timeSpent_pct))
`summarise()` regrouping output by 'instanceNumber', 'region', 'sol' (override with `.groups` argument)
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

plo = ggplot(dataInput2,aes(x=region,y=timeSpent_pct,fill=sol))+
  geom_boxjitter(jitter.color = NA,jitter.shape = 21,
                 jitter.params = list(height=0,seed=10),
                 outlier.shape =NA)+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0.5))+
  scale_fill_manual(name  ="Region",
                    breaks=c("1","0"),
                    labels=c("Satisfiable","Unsatisfiable"),
                    values=c("#90BE6D","#F94144"))+
  xlab("Typical Case Complexity (TCC)")+
  ylab("Time-on-task")+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  ylim(0.15,1)

plo
ggsave(paste0(folderOut_figures,"/TCC_SAT_time.pdf"),plo,width = 7,height =6,units="in")

1.3.2 Satsifiability and TCC


dataInput=dataTrial_SAT_Time %>% group_by(phaseT,sol,pID)%>%summarise(timeSpent1=mean(timeSpent))%>%ungroup()%>%group_by(sol,phaseT)%>%summarise(timeSpent=mean(timeSpent1),se=se(timeSpent1))%>%ungroup()
`summarise()` regrouping output by 'phaseT', 'sol' (override with `.groups` argument)
`summarise()` regrouping output by 'sol' (override with `.groups` argument)
sol_names <- c(
                    `0` = "Correct answer: NO",
                    `1` = "Correct answer: YES",
                    `2` = "If this is here it means data not filtered"
                    )

plo=ggplot(data=dataInput, aes(y=timeSpent, x=as.factor(as.logical(phaseT)), 
                               label = round(timeSpent,digits = 1),group=1)) +
  geom_line()+
  geom_errorbar(aes(ymin=timeSpent-se, ymax=timeSpent+se), width=.1) +
  geom_point(shape=21, size=3, fill="white")+
  labs(title="Time Spent segregated by solvability",x="In Phase Transition?",y="Time Spent")+
  theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(angle=0,hjust=0.5))+
  geom_text(hjust=-0.5, colour="black")+
  facet_grid(.~sol, labeller = as_labeller(sol_names))

outputName = "sat_time_03_g"
plotExport(plo,outputName,folderOut_figures)
[1] "sat_time_03_g"
quartz_off_screen 
                2 

dataInput= dataTrial_SAT_Time
#logistic with random effects (intercept)
dataInput$sol =as.factor(dataInput$sol)
dataInput$phaseT = as.factor(dataInput$phaseT)

# TTTODO
randomIntercept = brm2(timeSpent_pct | cens(censored_time) ~ phaseT + sol + phaseT:sol + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

title="Linear regressions"
tableName="sat_time_03_r"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

Marginal Effects

#marginal_effects(randomIntercept, ask=FALSE)
plot(marginal_effects(allModels[["sat_time_03_r"]]), plot = TRUE, ask = FALSE)
Method 'marginal_effects' is deprecated. Please use 'conditional_effects' instead.

1.3.3 Satisfiability

#st06
dataInput= dataTrial_SAT_Time
#logistic with random effects (intercept)
#dataInput$sol =as.factor(dataInput$sol)

randomIntercept = brm2(timeSpent_pct | cens(censored_time) ~ sol + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="sat_time_03_r_B"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

1.3.4 Region effect on time-on-task (Constrainedness)

dataInput=dataTrial_SAT_Time #%>% mutate(region=recode(type, `1`= 'Phase Transition', `2`= 'Phase Transition', `3`= 'Phase Transition', `4`='Phase Transition', '5'='Overconstrained', '6'='Underconstrained'))

dataInput2=dataInput %>% group_by(region,pID)%>%summarise(timeSpent1=mean(timeSpent))%>%ungroup()%>%group_by(region)%>%summarise(timeSpent=mean(timeSpent1),se=se(timeSpent1))%>%ungroup()
`summarise()` regrouping output by 'region' (override with `.groups` argument)
`summarise()` ungrouping output (override with `.groups` argument)
dataInput2$region <- factor(dataInput2$region, levels = c('Underconstrained',
                                                          'Phase Transition',
                                                          'Overconstrained'))

plo= ggplot(data=dataInput2, aes(y=timeSpent, x=region, label = round(timeSpent,digits = 1))) +
  geom_bar(stat = "identity")+
  geom_errorbar(aes(ymin=timeSpent-se, ymax=timeSpent+se), width=.1)+
  labs(title="time Spent by region",x="Region",y="time Spent")+
  #coord_cartesian(ylim = c(0.5,1))+
  geom_text(hjust=0.5,vjust = 5, colour="white") +
  theme_light()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),plot.title = element_text(hjust = 0.5))

outputName = "sat_time_04_g"
plotExport(plo,outputName,folderOut_figures)
[1] "sat_time_04_g"
quartz_off_screen 
                2 

#Stats test for time in and out of phase transition: ANOVA
dataInput$overConstrained= (dataInput$region=='Overconstrained')
dataInput$underConstrained= (dataInput$region=='Underconstrained')
randomIntercept = brm2(timeSpent_pct | cens(censored_time) ~ overConstrained + underConstrained + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="sat_time_04_g_A"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

Is there a difference between time-on-task between the overconstrained region and the underconstrained region?

fit = hypothesis(allModels[["sat_time_04_g_A"]],"overConstrainedTRUE=underConstrainedTRUE", seed=seed_brms)

print(fit)
Hypothesis Tests for class b:
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
hdi(fit$samples,ci=0.95)
# Highest Density Interval

Parameter |      95% HDI
------------------------
H1        | [0.38, 0.46]

1.3.5 Number of solution witnesses that satisfy the constraints

1.3.5.1 No. witnesses and TCC

dataInput=dataTrial_SAT_Time

#Plots nSolutions (x) vs. Accuracy (y)
dataInput3 = dataInput %>% group_by(nSolutions,pID,phaseT)%>%summarise(timeSpent1=mean(timeSpent))%>%ungroup()%>%group_by(nSolutions,phaseT)%>%summarise(timeSpent=mean(timeSpent1),se=se(timeSpent1))%>%ungroup()
`summarise()` regrouping output by 'nSolutions', 'pID' (override with `.groups` argument)
`summarise()` regrouping output by 'nSolutions' (override with `.groups` argument)
dataInput3$sol = dataInput3$nSolutions>=1
dataInput3$phaseT = recode(dataInput3$phaseT, '0' = "Low IC", '1' = "High IC")

plo= ggplot(data=dataInput3, aes(y=timeSpent, x=as.factor(nSolutions))) +
  geom_errorbar(aes(ymin=timeSpent-se, ymax=timeSpent+se), width=.1)+
  geom_point(shape=23, size=3, fill="red")+
  labs(title="Time Spent and the Number of Solutions",
       x="Number of   Solutions",y="Time Spent")+
  #coord_cartesian(ylim = c(0.5,1))+
  theme_light()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0.5),strip.text.x = element_blank())+
  facet_grid(phaseT~sol, scales = "free_x", space = "free_x")+
  geom_smooth(data=dataInput3, aes(y=timeSpent, x=nSolutions),method=glm,
              se=FALSE,fullrange=TRUE,linetype = "dashed")

outputName = "sat_time_05_g"
plotExport(plo,outputName,folderOut_figures)
[1] "sat_time_05_g"
quartz_off_screen 
                2 


# For satisfiable instance only
dataInput = dataInput %>% filter(sol==1)

randomIntercept = brm2(timeSpent_pct | cens(censored_time) ~ phaseT + nSolutions + phaseT:nSolutions + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="sat_time_05_r_A"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

This calculates the significance of the beta(slope) of the number of witnesses for instances with high TCC.

#This version recodes phaseT to OutphaseT, to 

fit = hypothesis(allModels[["sat_time_05_r_A"]],"nSolutions + phaseT:nSolutions = 0", seed=seed_brms)

#fit = hypothesis(randomIntercept,"nSolutions = 0", seed=seed_brms)

print(fit)
Hypothesis Tests for class b:
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
hdi(fit$samples,ci=0.95)
# Highest Density Interval

Parameter |        95% HDI
--------------------------
H1        | [-0.13, -0.04]
#summary(randomIntercept)

Marginal Effects

plot(marginal_effects(allModels[["sat_time_05_r_A"]]), plot = TRUE, ask = FALSE)
Method 'marginal_effects' is deprecated. Please use 'conditional_effects' instead.

1.3.5.2 NSol (Regressed alone)

#st07
dataInput= dataTrial_SAT_Time
dataInput = dataInput %>% filter(sol==1)
#logistic with random effects (intercept)
#dataInput$sol =as.factor(dataInput$sol)

randomIntercept = brm2(timeSpent_pct | cens(censored_time) ~  nSolutions + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="sat_time_05_r_B"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

#dataInput3
mean_acc = dataInput %>% group_by(instanceNumber,nSolutions, sol,phaseT) %>%
  summarise(accuracy=mean(correct),
            timeSpent_med =median(timeSpent)) 
`summarise()` regrouping output by 'instanceNumber', 'nSolutions', 'sol' (override with `.groups` argument)
logitRandomIntercept = allModels[['sat_time_05_r_B']]
pp  = plot(conditional_effects(logitRandomIntercept,
           probs = c(0.025,0.975)), plot = FALSE, ask = FALSE)

pp$nSolutions + 
  geom_point(data=mean_acc,aes(x = nSolutions, y = timeSpent_med/SATTaskMaxTime),inherit.aes = FALSE)

NA
NA
# Improving the plot

size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

pp_plot = pp$nSolutions
pp_plot$layers[[1]]$geom_params$se = FALSE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_boxplot(data=dataInput,
                                      aes(x = nSolutions, 
                                          group = nSolutions, 
                                          y = timeSpent_pct), 
                                      inherit.aes = FALSE),
                        geom_point(data=mean_acc, 
                                   aes(x = nSolutions, y = timeSpent_med/SATTaskMaxTime,
                                       col=as.factor(sol), shape=as.factor(phaseT), size=2.5),
                                   inherit.aes = FALSE),
                         pp_plot$layers)

plo = pp_plot +
  xlab("Number of solution Witnesses")+#expression(IC[expost]))+
  ylab("Time-on-task")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  ylim(0, 1)+
  scale_x_continuous(breaks = c(1,3,5,7,9),limits =c(0.5,10.5))+
  guides(shape = guide_legend(override.aes = list(size = 3)))

plo
ggsave(paste0(folderOut_figures,"/Nwit_SAT_time.pdf"),plo,width = 6,height =6,units="in")

# Improving the plot

size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

pp_plot = pp$nSolutions
pp_plot$layers[[1]]$geom_params$se = TRUE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_point(data=dataInput,
                               aes(x = nSolutions, y = timeSpent_pct,
                                   shape=as.factor(phaseT), size=0.4,
                                   alpha = 0.5),
                                   inherit.aes = FALSE),
                    geom_point(data=mean_acc, 
                                   aes(x = nSolutions, 
                                       y = timeSpent_med/SATTaskMaxTime,
                                       col=as.factor(sol),
                                       shape=as.factor(phaseT), size=2.5),
                                   inherit.aes = FALSE),
                         pp_plot$layers)


plo = pp_plot +
  xlab("Number of solution Witnesses")+#expression(IC[expost]))+
  ylab("Time-on-task")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+#c( "#FC4E07","#E7B800")
  # scale_shape_manual(name="IC",values = c(2, 8))+
  # scale_color_manual(name="Solution",values = c("red", "blue"))+
  theme_classic()+

  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  ylim(0, 1)+
  scale_x_continuous(breaks = c(1,3,5,7,9),limits =c(0.5,10.5))+
  guides(shape = guide_legend(override.aes = list(size = 3)))

plo
ggsave(paste0(folderOut_figures,"/Nwit_SAT_time2.pdf"),plo,width = 6,height =6,units="in")

1.3.6 IC_expost (distance from the optimum)

dataInput = dataTrial_SAT_Time
# Summarise the data to plot
mean_accuracy_time = dataInput %>% 
  group_by(instanceNumber, sol, ICexpost, phaseT, nSolutions) %>% 
  summarise(accuracy = mean(correct), 
            timeSpent_med = median(timeSpent),
            timeSpent = mean(timeSpent))
`summarise()` regrouping output by 'instanceNumber', 'sol', 'ICexpost', 'phaseT' (override with `.groups` argument)
ggplot(mean_accuracy_time,aes(x = ICexpost, y = timeSpent))+
  geom_point() +
  theme_light() +
  stat_smooth(formula =  y ~ I(x^0.01), method="lm", se= FALSE)+
  xlab("IC_expost")+
  ylab("Time Spent")

1.3.6.0.1 Unsatisfiable instances
dataInput = dataTrial_SAT_Time %>% filter(sol==0)

model_ICexpost = brm2(timeSpent_pct | cens(censored_time) ~ ICexpost + (1|pID),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0, iter = iters_high)

tableName='sat_time_icexpost'
save_summarise_model(model_ICexpost, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

1.3.6.0.2 All instances
dataInput = dataTrial_SAT_Time

model_ICexpost = brm2(timeSpent_pct | cens(censored_time) ~ ICexpost + (1|pID),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0, iter = iters_high)

tableName='sat_time_icexpost2'
save_summarise_model(model_ICexpost, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

Marginal Effects

mean_accuracy_time$correct= mean_accuracy_time$accuracy
#mean_accuracy_time$ICexpost05 = mean_accuracy_time$ICexpost^0.5

model_ICexpost = allModels[['sat_time_icexpost2']]
pp  = plot(conditional_effects(model_ICexpost), plot = FALSE, ask = FALSE)

pp$ICexpost + 
  geom_point(data=mean_accuracy_time,aes(x = ICexpost, y = timeSpent/SATTaskMaxTime),inherit.aes = FALSE)

# Improving the plot option 2

pp_plot = pp$ICexpost
pp_plot$layers[[1]]$geom_params$se = TRUE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_point(data=dataInput,
                               aes(x = ICexpost, y = timeSpent_pct,
                                   shape=as.factor(phaseT), size=0.4,
#                                   col=as.factor(sol),
                                   alpha = 0.2),
                                   inherit.aes = FALSE),
                    geom_point(data=mean_accuracy_time, 
                                   aes(x = ICexpost, 
                                       y = timeSpent_med/SATTaskMaxTime,
                                       col=as.factor(sol),
                                       shape=as.factor(phaseT), size=2.5),
                                   inherit.aes = FALSE),
                         pp_plot$layers)

size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

plo = pp_plot +
  xlab("Instance Complexity (IC)")+#expression(IC[expost]))+
  ylab("Time-on-task")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+#c( "#FC4E07","#E7B800")
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  ylim(0, 1.1)+
  scale_y_continuous(breaks = c(0,0.25,0.5,0.75,1))+
  guides(shape = guide_legend(override.aes = list(size = 3)))
Scale for 'y' is already present. Adding another scale for 'y', which will
replace the existing scale.
plo
ggsave(paste0(folderOut_figures,"/IC_SAT_time1.pdf"),plo,width = 6,height =6,units="in")

1.4 Time-on-task and Accuracy


dataInput= dataTrial_SAT_Time %>% group_by(correct,pID) %>% summarise(timeSpentMeans=mean(timeSpent)) %>% ungroup() %>% group_by(correct) %>%
  summarise(time=mean(timeSpentMeans),se=se(timeSpentMeans))%>%ungroup()
`summarise()` regrouping output by 'correct' (override with `.groups` argument)
`summarise()` ungrouping output (override with `.groups` argument)
plo = ggplot(data=dataInput, aes(y=time, x=as.factor(as.logical(correct)), label = round(time,digits = 2),group=1)) +
  geom_line()+
  geom_errorbar(aes(ymin=time-se, ymax=time+se), width=.1) +
  geom_point(shape=21, size=3, fill="white")+
  labs(title="Time Spent on Correct/Incorrect instances",x="Answer Correct?",y="Time Spent") +
  theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(angle=0,hjust=0.5))+
  geom_text(hjust=-0.5, colour="black")

outputName = "sat_time_09_g"
plotExport(plo,outputName,folderOut_figures)
[1] "sat_time_09_g"
quartz_off_screen 
                2 

dataInput = dataTrial_SAT_Time
#Stats test for time for correct/incorrect answers
logitRandomIntercept = brm2(correct ~ timeSpent_pct + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput, 
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms, refresh = 0)


tableName="sat_time_09_r"
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

1.5 Number of Clicks

1.5.0.1 Satisfiability

dataInput=dataTrial_SAT_clicks

# BOXPLOT
plo= ggplot(data=dataInput, aes(y=n_clicks, x=region, label = round(n_clicks,digits = 0))) +
  geom_boxplot()+
  labs(x="Region",y="n_clicks")+
  #coord_cartesian(ylim = c(0.5,1))+
  geom_text(hjust=0.5,vjust = 5, colour="white") +
  theme_light()+
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(),plot.title = element_text(hjust = 0.5))+
  facet_grid(.~sol)


outputName = 'sat_acc_04_g'
plotExport(plo,outputName,folderOut_figures)
[1] "sat_acc_04_g"
quartz_off_screen 
                2 

Nice Plot:

size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

dataInput2 = dataTrial_SAT_clicks %>% 
  mutate(region = fct_relevel(region,
                              "Underconstrained", "Phase Transition", "Overconstrained"))%>% 
  mutate(sol= as.factor(sol)) %>% 
  mutate(sol = fct_relevel(sol,"1", "0"))

dataInput3 = dataInput2 %>% 
  group_by(instanceNumber,region,sol) %>% 
  summarise(n_clicks=mean(n_clicks))
`summarise()` regrouping output by 'instanceNumber', 'region' (override with `.groups` argument)
plo = ggplot(dataInput3,aes(x=region,y=n_clicks,fill=sol))+
  # geom_boxjitter(aes(fill=region),jitter.color = NA,jitter.shape = 21)+
  geom_boxjitter(jitter.color = NA,jitter.shape = 21,
                 jitter.params = list(height=0,seed=10),
                 outlier.shape= NA)+
                 #,outlier.shape = 4, outlier.size=0.9)+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0.5))+
  scale_fill_manual(name  ="Region",
                    breaks=c("1","0"),
                    labels=c("Satisfiable","Unsatisfiable"),
                    values=c("#90BE6D","#F94144"))+
  xlab("Typical Case Complexity (TCC)")+
  ylab("Number of clicks")+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))+
  ylim(0,20)


plo
ggsave(paste0(folderOut_figures,"/TCC_SAT_nclicks.pdf"),plo,width = 7,height =6,units="in")

#Logistic Regression for In/Out Phase transition
dataInput= dataTrial_SAT_clicks

#logistic with random effects (intercept)
# TTTODO
randomIntercept = brm2(n_clicks| cens(censored_clicks) ~ sol + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="sat_clicks_01_r"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

1.5.0.2 TCC

#Logistic Regression for In/Out Phase transition
dataInput= dataTrial_SAT_clicks

#logistic with random effects (intercept)
# TTTODO
randomIntercept = brm2(n_clicks| cens(censored_clicks) ~ phaseT + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="sat_clicks_02_r"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

1.5.0.2.1 And Satisfiability
dataInput= dataTrial_SAT_clicks

#logistic with random effects (intercept)
dataInput$phaseT = as.factor(dataInput$phaseT)
dataInput$sol = as.factor(dataInput$sol)
randomIntercept = brm2(n_clicks| cens(censored_clicks) ~ phaseT + sol + phaseT:sol + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="sat_clicks_02B_r"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

pp  = plot(conditional_effects(allModels[["sat_clicks_02B_r"]]), plot = TRUE, ask = FALSE)

1.5.0.3 ICexpost

#Logistic Regression for In/Out Phase transition
dataInput= dataTrial_SAT_clicks

#logistic with random effects (intercept)
randomIntercept = brm2(n_clicks| cens(censored_clicks) ~ ICexpost + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="sat_clicks_03_r"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

dataInput = dataTrial_SAT_clicks
# Summarise the data to plot
mean_nclicks = dataInput %>% 
  group_by(instanceNumber, sol, ICexpost, phaseT, nSolutions) %>% 
  summarise(n_clicks = median(n_clicks))
`summarise()` regrouping output by 'instanceNumber', 'sol', 'ICexpost', 'phaseT' (override with `.groups` argument)
model_ICexpost = allModels[["sat_clicks_03_r"]]
pp  = plot(conditional_effects(model_ICexpost), plot = FALSE, ask = FALSE)

pp$ICexpost +
  geom_point(data=mean_nclicks,aes(x = ICexpost, y =n_clicks),inherit.aes = FALSE)

# Improving the plot
# Improving the plot
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

pp_plot = pp$ICexpost
pp_plot$layers[[1]]$geom_params$se = FALSE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_point(data=mean_nclicks,
                               aes(x = ICexpost, y = n_clicks, col=as.factor(sol),
                                   shape=as.factor(phaseT), size=2.5), inherit.aes = FALSE),
                         pp_plot$layers)


plo = pp_plot +
  xlab("Instance Complexity (IC)")+#expression(IC[expost]))+
  ylab("Number of Clicks")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))

plo
ggsave(paste0(folderOut_figures,"/IC_SAT_nclicks.pdf"),plo,width = 6,height =6,units="in")

Only Unsatisfiable:

#Logistic Regression for In/Out Phase transition
dataInput= dataTrial_SAT_clicks %>% filter(sol==0)

#logistic with random effects (intercept)
# TTTODO
randomIntercept = brm2(n_clicks| cens(censored_clicks) ~ ICexpost + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="sat_clicks_03_rB"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

dataInput= dataTrial_SAT_clicks #%>% filter(sol==0)
# Summarise the data to plot
mean_nclicks = dataInput %>% 
  group_by(instanceNumber, sol, ICexpost, phaseT, nSolutions) %>% 
  summarise(n_clicks = median(n_clicks))
`summarise()` regrouping output by 'instanceNumber', 'sol', 'ICexpost', 'phaseT' (override with `.groups` argument)
model_ICexpost = allModels[["sat_clicks_03_rB"]]
pp  = plot(conditional_effects(model_ICexpost), plot = FALSE, ask = FALSE)

pp$ICexpost +
  geom_point(data=mean_nclicks,aes(x = ICexpost, y =n_clicks),inherit.aes = FALSE)

# Improving the plot
# Improving the plot
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

pp_plot = pp$ICexpost
pp_plot$layers[[1]]$geom_params$se = FALSE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_jitter(data=dataInput,
                               aes(x = ICexpost, y = n_clicks,
                                   shape=as.factor(phaseT), size=0.4,
#                                   col=as.factor(sol),
                                   alpha = 0.2),
                                   inherit.aes = FALSE,height=0.2),
                        geom_point(data=mean_nclicks, 
                                   aes(x = ICexpost, y = n_clicks,
                                       col=as.factor(sol), shape=as.factor(phaseT), size=2.5),
                                   inherit.aes = FALSE),
                         pp_plot$layers)

plo = pp_plot +
  xlab("Instance Complexity (IC)")+#expression(IC[expost]))+
  ylab("Number of Clicks")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))+ 
  xlim(0,0.09)

plo
ggsave(paste0(folderOut_figures,"/IC_SAT_nclicks_unsat.pdf"),plo,width = 6,height =6,units="in")

1.5.0.3.1 And Satisfiability
dataInput= dataTrial_SAT_clicks

#logistic with random effects (intercept)
dataInput$unsol = abs(dataInput$sol-1)
randomIntercept = brm2(n_clicks| cens(censored_clicks) ~ unsol + unsol:ICexpost + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="sat_clicks_03_rC"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

pp  = plot(conditional_effects(allModels[["sat_clicks_03_rC"]]), plot = TRUE, ask = FALSE)

1.5.0.4 Nsolutions

dataInput= dataTrial_SAT_clicks

#logistic with random effects (intercept)
# TTTODO
randomIntercept = brm2(n_clicks| cens(censored_clicks) ~ nSolutions + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="sat_clicks_04_r"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

Only Satisfiable:

dataInput= dataTrial_SAT_clicks %>% filter(sol==1)

#logistic with random effects (intercept)
# TTTODO
randomIntercept = brm2(n_clicks| cens(censored_clicks) ~ nSolutions + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="sat_clicks_04_rB"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

#dataInput = dataTrial_SAT_clicks
# Summarise the data to plot
mean_nclicks = dataInput %>% 
  group_by(instanceNumber, sol, ICexpost, phaseT, nSolutions) %>% 
  summarise(n_clicks = median(n_clicks))
`summarise()` regrouping output by 'instanceNumber', 'sol', 'ICexpost', 'phaseT' (override with `.groups` argument)
model_ICexpost = allModels[["sat_clicks_04_rB"]]
pp  = plot(conditional_effects(model_ICexpost), plot = FALSE, ask = FALSE)

pp$nSolutions +
  geom_point(data=mean_nclicks,aes(x = nSolutions, y =n_clicks),inherit.aes = FALSE)

# Improving the plot
# Improving the plot
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

pp_plot = pp$nSolutions
pp_plot$layers[[1]]$geom_params$se = FALSE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_jitter(data=dataInput,
                               aes(x = nSolutions, y = n_clicks,
                                   shape=as.factor(phaseT), size=0.4,
#                                   col=as.factor(sol),
                                   alpha = 0.2),
                                   inherit.aes = FALSE,width=0.2,height =0.2),
                        geom_point(data=mean_nclicks, 
                                   aes(x = nSolutions, y = n_clicks,
                                       col=as.factor(sol), shape=as.factor(phaseT), size=2.5),
                                   inherit.aes = FALSE),
                         pp_plot$layers)

plo = pp_plot +
  xlab("Number of Solution Witnesses")+
  ylab("Number of Clicks")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))

plo
ggsave(paste0(folderOut_figures,"/Nwit_SAT_nclicks.pdf"),plo,width = 6,height =6,units="in")

2 Traveling salesperson Problem

2.1 Functions

calculate_tsp_ICexpost =function(opt,max_dist){
  ICexpost  =  abs(opt- max_dist)/opt
  return(ICexpost)
}

2.2 Accuracy

Read Clean Data to file


dataTrial_TSP= read_csv2(file.path(data_folder,"TSP_clean.csv"))
Using ',' as decimal and '.' as grouping mark. Use read_delim() for more control.
Parsed with column specification:
cols(
  .default = col_double(),
  pID = col_character(),
  itemsSelected = col_character(),
  error = col_logical(),
  cx = col_character(),
  cy = col_character(),
  distances = col_character(),
  id = col_character(),
  region = col_character()
)
See spec(...) for full column specifications.
dataTrial_TSP_Time = read_csv2(file.path(data_folder,"TSP_clean_time.csv"))
Using ',' as decimal and '.' as grouping mark. Use read_delim() for more control.
Parsed with column specification:
cols(
  .default = col_double(),
  pID = col_character(),
  itemsSelected = col_character(),
  error = col_logical(),
  cx = col_character(),
  cy = col_character(),
  distances = col_character(),
  id = col_character(),
  region = col_character()
)
See spec(...) for full column specifications.
dataTrial_TSP_Time$timeSpent_pct = dataTrial_TSP_Time$timeSpent/TSPTaskMaxTime

color_scheme_set("purple")

dataTrial_TSP$censored_time = ifelse(dataTrial_TSP$timeSpent == TSPTaskMaxTime,
                             "right","none")

dataTrial_TSP_Time$censored_time = ifelse(dataTrial_TSP_Time$timeSpent == TSPTaskMaxTime,
                             "right","none")

instanceProperties_TSP= read_csv2(paste0(data_folder,"instance_properties_TSP.csv"))
Using ',' as decimal and '.' as grouping mark. Use read_delim() for more control.
Parsed with column specification:
cols(
  instanceNumber = col_double(),
  nSolutions = col_double(),
  opt_distance = col_double(),
  opt_tour = col_character(),
  cx = col_character(),
  cy = col_character(),
  distances = col_character(),
  id = col_character(),
  type = col_double(),
  sol = col_double(),
  max_distance = col_double(),
  nCities = col_double(),
  param = col_character(),
  dist_from_opt = col_double()
)
instanceProperties_TSP =instanceProperties_TSP %>% 
  select(instanceNumber,nSolutions,opt_distance,opt_tour,dist_from_opt)

dataTrial_TSP = left_join(dataTrial_TSP,instanceProperties_TSP, by = "instanceNumber")
dataTrial_TSP_Time = left_join(dataTrial_TSP_Time,instanceProperties_TSP, by = "instanceNumber")

dataTrial_TSP$ICexpost = calculate_tsp_ICexpost(dataTrial_TSP$opt_distance,
                                          dataTrial_TSP$max_distance)

dataTrial_TSP_Time$ICexpost = calculate_tsp_ICexpost(dataTrial_TSP_Time$opt_distance,
                                          dataTrial_TSP_Time$max_distance)


data_TSP_clicks = read_csv2(file.path(data_folder,"TSP_clicks.csv"))
Using ',' as decimal and '.' as grouping mark. Use read_delim() for more control.
Parsed with column specification:
cols(
  pID = col_character(),
  block = col_double(),
  trial = col_double(),
  citynumber.100.Reset. = col_double(),
  In.1..Out.0..Reset.3. = col_double(),
  time = col_double()
)
nClicks = data_TSP_clicks %>% group_by(pID,block,trial) %>% summarise(n_clicks =n())
`summarise()` regrouping output by 'pID', 'block' (override with `.groups` argument)
#View(nClicks)

dataTrial_TSP_clicks=merge(nClicks,
                  dataTrial_TSP, by=c("pID","block","trial"))
#Summary Stats for Decision Problem
dataInput=dataTrial_TSP

accuracySummary = dataInput %>% group_by(pID) %>% summarise(acc=mean(correct)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))

summarise() ungrouping output (override with .groups argument)

kable(accuracySummary, digits=2, caption = "Accuracy Summary")

Accuracy Summary
mean min max SD
0.85 0.76 0.93 0.05


answerSummary = dataInput %>% group_by(pID) %>% summarise(acc=mean(answer)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))

summarise() ungrouping output (override with .groups argument)

kable(answerSummary, digits=2, caption = "Proportion of times that YES was selected as the answer")

Proportion of times that YES was selected as the answer
mean min max SD
0.5 0.35 0.68 0.09


yesNoProportions = dataInput %>% group_by(sol,pID) %>% summarise(acc=mean(correct)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))

summarise() regrouping output by ‘sol’ (override with .groups argument) summarise() ungrouping output (override with .groups argument)

kable(yesNoProportions, digits=2, caption = "Accuracy By Solution")

Accuracy By Solution
sol mean min max SD
0 0.86 0.63 1 0.11
1 0.85 0.69 1 0.09

NA

2.2.1 Effect of trial number on accuracy

#Trial (experience effect) effect
dataInput=dataTrial_TSP

#Summary
summaryByBlock = dataInput %>% group_by(block,pID) %>% summarise(acc=mean(correct)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))
`summarise()` regrouping output by 'block' (override with `.groups` argument)
`summarise()` ungrouping output (override with `.groups` argument)
kable(summaryByBlock, digits=2, caption = "Accuracy By Block Number")

Accuracy By Block Number
block mean min max SD
1 0.83 0.58 0.96 0.09
2 0.86 0.75 0.96 0.06
3 0.87 0.71 1.00 0.08


#Regresssion
dataInput$totalTrial = dataInput$block * dataInput$trial

logitRandomIntercept = brm2(correct ~ totalTrial+ (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0)

tableName='tsp_acc_01_r'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

2.2.2 TCC

dataInput=dataTrial_TSP %>% group_by(phaseT,pID)%>%summarise(accuracy1=mean(correct))%>%ungroup()%>%group_by(phaseT)%>%summarise(accuracy=mean(accuracy1),se=se(accuracy1))%>%ungroup()
`summarise()` regrouping output by 'phaseT' (override with `.groups` argument)
`summarise()` ungrouping output (override with `.groups` argument)
dataInput$phaseT = recode(dataInput$phaseT, '0' = "Low IC", '1' = "High IC")

plo= ggplot(data=dataInput, aes(y=accuracy, x=as.factor(phaseT),label = round(accuracy,digits = 2))) +
  geom_bar(stat = "identity")+
  geom_errorbar(aes(ymin=accuracy-se, ymax=accuracy+se), width=.1)+
  #geom_signif(comparisons = list(c("Low IC","High IC")), annotations="***", y_position = 0.95, tip_length = 0.03)+
  labs(title="Accuracy In and Out of phase Transition",x="Instance complexity",y="Accuracy")+
  coord_cartesian(ylim = c(0.5,1))+
  geom_text(hjust=0.5,vjust = 5, colour="white")+
  theme_light()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),plot.title = element_text(hjust = 0.5))

outputName = 'tsp_acc_02_g'
plotExport(plo,outputName,folderOut_figures)
[1] "tsp_acc_02_g"
quartz_off_screen 
                2 

#Logistic Regression for In/Out Phase transition
dataInput= dataTrial_TSP

#logistic with random effects (intercept)
logitRandomIntercept = brm2(correct ~ phaseT + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput, 
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms, refresh = 0)

tableName='tsp_acc_02_r'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

2.2.2.1 Plot TCC

dataInput = dataTrial_TSP

dataInput = dataInput %>% 
  mutate(region = fct_relevel(region,
                              "Underconstrained", "Phase Transition", "Overconstrained")) %>% 
  mutate(sol= as.factor(sol)) %>% 
  mutate(sol = fct_relevel(sol,"1", "0"))

dataInput2 = dataInput %>% 
  group_by(instanceNumber,region,sol) %>% 
  summarise(accuracy=mean(correct))
`summarise()` regrouping output by 'instanceNumber', 'region' (override with `.groups` argument)
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7


plo = ggplot(dataInput2,aes(x=region,y=accuracy,fill=sol))+
  # geom_boxjitter(aes(fill=region),jitter.color = NA,jitter.shape = 21)+
  geom_boxjitter(jitter.color = NA,jitter.shape = 21,
                 jitter.params = list(height=0,seed=10),
                 outlier.shape= NA)+
                 #,outlier.shape = 4, outlier.size=0.9)+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0.5))+
  scale_fill_manual(name  ="Region",
                    breaks=c("1","0"),
                    labels=c("Satisfiable","Unsatisfiable"),
                    values=c("#90BE6D","#F94144"))+
  xlab("Typical Case Complexity (TCC)")+
  ylab("Human Performance")+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))+
  ylim(0.2,1)


plo
ggsave(paste0(folderOut_figures,"/TCC_TSP_acc.pdf"),plo,width = 7,height =6,units="in")

2.2.3 Satsifiability and TCC


dataInput=dataTrial_TSP %>% group_by(phaseT,sol,pID)%>%summarise(accuracy1=mean(correct))%>%ungroup()%>%group_by(sol,phaseT)%>%summarise(accuracy=mean(accuracy1),se=se(accuracy1))%>%ungroup()
`summarise()` regrouping output by 'phaseT', 'sol' (override with `.groups` argument)
`summarise()` regrouping output by 'sol' (override with `.groups` argument)
sol_names <- c(
                    `0` = "Correct answer: NO",
                    `1` = "Correct answer: YES",
                    `2` = "If this is here it means data not filtered"
                    )

plo=ggplot(data=dataInput, aes(y=accuracy, x=as.factor(as.logical(phaseT)), label = round(accuracy,digits = 2),group=1)) +
  geom_line()+
  geom_errorbar(aes(ymin=accuracy-se, ymax=accuracy+se), width=.1) +
  geom_point(shape=21, size=3, fill="white")+
  labs(title="Accuracy segregated by solvability",x="In Phase Transition?",y="Accuracy")+
  theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(angle=0,hjust=0.5))+
  geom_text(hjust=-0.5, colour="black")+
  facet_grid(.~sol, labeller = as_labeller(sol_names))

outputName = 'tsp_acc_03_g'
plotExport(plo,outputName,folderOut_figures)
[1] "tsp_acc_03_g"
quartz_off_screen 
                2 

dataInput= dataTrial_TSP

dataInput$phaseT = as.factor(dataInput$phaseT)
dataInput$sol = as.factor(dataInput$sol)

#logistic with random effects (intercept)
logitRandomIntercept = brm2(correct ~ phaseT + sol + phaseT:sol + (1|pID), 
                           family=bernoulli(link="logit"),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms, refresh = 0)

tableName='tsp_acc_03_r'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

Marginal effects

plot(marginal_effects(allModels[['tsp_acc_03_r']]), plot = TRUE, ask = FALSE)
Method 'marginal_effects' is deprecated. Please use 'conditional_effects' instead.

Effect of TCC on satisfiable instances

#st01
model = allModels[['tsp_acc_03_r']]

fit = hypothesis(model,"phaseT1+ phaseT1:sol1=0", seed=seed_brms)

print(fit)
Hypothesis Tests for class b:
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
hdi(fit$samples,ci=0.95)
# Highest Density Interval

Parameter |        95% HDI
--------------------------
H1        | [-2.61, -1.52]

2.2.3.1 Only satisfiability

dataInput= dataTrial_TSP
dataInput$sol = as.factor(dataInput$sol)

#logistic with random effects (intercept)
logitRandomIntercept = brm2(correct ~ sol + (1|pID), 
                           family=bernoulli(link="logit"),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms, refresh = 0)

tableName='tsp_acc_03B_r'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

2.2.4 Region effect on Accuracy (Constrainedness)

dataInput=dataTrial_TSP

dataInput2=dataInput %>% group_by(region,pID)%>%summarise(accuracy1=mean(correct))%>%ungroup()%>%group_by(region)%>%summarise(accuracy=mean(accuracy1),se=se(accuracy1))%>%ungroup()
`summarise()` regrouping output by 'region' (override with `.groups` argument)
`summarise()` ungrouping output (override with `.groups` argument)
dataInput2$region <- factor(dataInput2$region, levels = c('Underconstrained',
                                                          'Phase Transition',
                                                          'Overconstrained'))

plo= ggplot(data=dataInput2, aes(y=accuracy, x=region, label = round(accuracy,digits = 2))) +
  geom_bar(stat = "identity")+
  geom_errorbar(aes(ymin=accuracy-se, ymax=accuracy+se), width=.1)+
  labs(title="Accuracy by region",x="Region",y="Accuracy")+
  coord_cartesian(ylim = c(0.5,1))+
  geom_text(hjust=0.5,vjust = 5, colour="white") +
  theme_light()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),plot.title = element_text(hjust = 0.5))

outputName = 'tsp_acc_04_g'
plotExport(plo,outputName,folderOut_figures)
[1] "tsp_acc_04_g"
quartz_off_screen 
                2 

#Stats test for time in and out of phase transition: ANOVA
dataInput$overConstrained= (dataInput$region=='Overconstrained')
dataInput$underConstrained= (dataInput$region=='Underconstrained')
logitRandomIntercept = brm2(correct ~ overConstrained + underConstrained + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput, 
                           chains=chains_brms,
                           cores = cores_brms,                            seed=seed_brms, refresh = 0)

tableName='tsp_acc_04_r_A'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

Is there a difference between accuracy in the overconstrained region and the underconstrained region?


fit = hypothesis(allModels[['tsp_acc_04_r_A']],"overConstrainedTRUE=underConstrainedTRUE", seed=seed_brms)

print(fit)
Hypothesis Tests for class b:
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
hdi(fit$samples,ci=0.95)
# Highest Density Interval

Parameter |       95% HDI
-------------------------
H1        | [-0.61, 0.84]

Region effect on accuracy by region and satisfiability

dataInput=dataTrial_TSP 

# dataInput$pID=as.character(dataInput$pID)
# ps = sample(pull(dataInput,pID),20)
# dataInput = dataInput %>% filter(pID %in% ps)

dataInput2=dataInput %>% group_by(region,pID,sol)%>%summarise(accuracy1=mean(correct))%>%ungroup()%>%group_by(region,sol)%>%summarise(accuracy=mean(accuracy1),se=se(accuracy1))%>%ungroup()
`summarise()` regrouping output by 'region', 'pID' (override with `.groups` argument)
`summarise()` regrouping output by 'region' (override with `.groups` argument)
dataInput2$region <- factor(dataInput2$region, levels = c('Underconstrained',
                                                          'Phase Transition',
                                                          'Overconstrained'))

dataInput2$sol = recode(dataInput2$sol, '1' = "Solvable", '0' = "Non-Solvable")

plo= ggplot(data=dataInput2, aes(y=accuracy, x=region, label = round(accuracy,digits = 2))) +
  geom_bar(stat = "identity")+
  geom_errorbar(aes(ymin=accuracy-se, ymax=accuracy+se), width=.1)+
  labs(title="Accuracy by region",x="Region",y="Accuracy")+
  coord_cartesian(ylim = c(0.5,1))+
  geom_text(hjust=0.5,vjust = 5, colour="white") +
  theme_light()+
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(),plot.title = element_text(hjust = 0.5))+
  facet_grid(.~sol)


outputName = 'tsp_acc_05_g'
plotExport(plo,outputName,folderOut_figures)
[1] "tsp_acc_05_g"
quartz_off_screen 
                2 

#Stats test for time in and out of phase transition: ANOVA
dataInput$overConstrained= (dataInput$region=='Overconstrained')
dataInput$underConstrained= (dataInput$region=='Underconstrained')

2.2.5 Number of solution witnesses

Difference in the number of witnesses for instances with low/high TCC

#Number of solutions of solvable solutions: Mean difference between low/high TCC

dataInput2 = unique(dataInput %>% select(phaseT,id,nSolutions,sol) %>% filter(sol==1))
diffMeans = t.test(nSolutions ~ phaseT ,data=dataInput2)
pander(diffMeans)

-------------------------------------------------------------------
 Test statistic    df         P value       Alternative hypothesis 
---------------- ------- ----------------- ------------------------
     7.264        32.84   2.543e-08 * * *         two.sided        
-------------------------------------------------------------------

Table: Welch Two Sample t-test: `nSolutions` by `phaseT` (continued below)

 
-----------------------------------
 mean in group 0   mean in group 1 
----------------- -----------------
      26208             4720       
-----------------------------------
dataInput=dataTrial_TSP

#Plots nSolutions (x) vs. Accuracy (y)
dataInput3 = dataInput %>% group_by(nSolutions,pID,phaseT)%>%summarise(accuracyMeans=mean(correct))%>%ungroup()%>%group_by(nSolutions,phaseT)%>%summarise(accuracy=mean(accuracyMeans),se=se(accuracyMeans))%>%ungroup()
`summarise()` regrouping output by 'nSolutions', 'pID' (override with `.groups` argument)
`summarise()` regrouping output by 'nSolutions' (override with `.groups` argument)
dataInput3$sol = as.factor(dataInput3$nSolutions>=1)
dataInput3$phaseT = recode(dataInput3$phaseT, '0' = "Low IC", '1' = "High IC")
dataInput3$nSolutions=dataInput3$nSolutions+1
  
plo=  ggplot(data=dataInput3, aes(y=accuracy, x=nSolutions)) +
  geom_errorbar(aes(ymin=accuracy-se, ymax=accuracy+se), width=.1)+
  geom_point(shape=23, size=3, fill="red")+
  labs(title="Accuracy and the Number of Solutions",
       x="log(Number of Solutions)",y="Accuracy")+
  coord_cartesian(ylim = c(0.3,1))+
  theme_light()+
  scale_x_log10()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0.5),strip.text.x = element_blank())+
  facet_grid(phaseT~sol, scales = "free_x", space = "free_x")+
  geom_smooth(data=dataInput3, aes(y=accuracy, x=nSolutions),method=glm,se=FALSE,fullrange=TRUE,linetype = "dashed")


outputName = 'tsp_nsol_acc_g'
plotExport(plo,outputName,folderOut_figures)
[1] "tsp_nsol_acc_g"
quartz_off_screen 
                2 

dataInput=dataTrial_TSP

dataInput = dataInput %>% filter(sol==1)

dataInput$nSolutions_log =log(dataInput$nSolutions)
logitRandomIntercept = brm2(correct ~ nSolutions_log + phaseT + phaseT:nSolutions_log + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0)

tableName='tsp_acc_ns1'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

This calculates the significance of the p-value of the beta(slope) of number of witnesses for instances with high TCC.

fit = hypothesis(allModels[['tsp_acc_ns1']],"nSolutions_log + nSolutions_log:phaseT = 0", seed=seed_brms)

print(fit)
Hypothesis Tests for class b:
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
hdi(fit$samples,ci=0.95)
# Highest Density Interval

Parameter |      95% HDI
------------------------
H1        | [0.31, 0.54]

Marginal Effects

plot(marginal_effects(allModels[['tsp_acc_ns1']]), plot = TRUE, ask = FALSE)
Method 'marginal_effects' is deprecated. Please use 'conditional_effects' instead.

2.2.5.1 NSol (regressed alone)

#st02
dataInput=dataTrial_TSP
dataInput = dataInput %>% filter(sol==1)
dataInput$nSolutions_log =log(dataInput$nSolutions)

#Includes a dummy if nSolutions==0, that's variable: sol.
logitRandomIntercept = brm2(correct ~ nSolutions_log + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput, 
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms, refresh = 0)

tableName='tsp_acc_ns2'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

mean_acc = dataInput %>% group_by(instanceNumber,nSolutions_log, sol,phaseT) %>%
  summarise(accuracy=mean(correct)) 
`summarise()` regrouping output by 'instanceNumber', 'nSolutions_log', 'sol' (override with `.groups` argument)
logitRandomIntercept = allModels[['tsp_acc_ns2']]
pp  = plot(conditional_effects(logitRandomIntercept), plot = FALSE, ask = FALSE)

pp$nSolutions_log + 
  geom_point(data=mean_acc,aes(x = nSolutions_log, y = accuracy),inherit.aes = FALSE)

# Improving the plot
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

pp_plot = pp$nSolutions_log
pp_plot$layers[[1]]$geom_params$se = FALSE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_point(data=mean_acc,
                               aes(x = nSolutions_log, y = accuracy, col=as.factor(sol),
                                   shape=as.factor(phaseT), size=2.5), inherit.aes = FALSE),
                         pp_plot$layers)


plo = pp_plot +
  xlab("Number of solution Witnesses (ln)")+#expression(IC[expost]))+
  ylab("Human Performance")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  scale_x_continuous(breaks = c(log(1),log(10),log(100),log(1000),log(10000)),
                     limits =c(0,NA),labels = c("1","10","100","1000","10000") )+
  guides(shape = guide_legend(override.aes = list(size = 3)))+
  ylim(0.2,1)


plo
ggsave(paste0(folderOut_figures,"/Nwit_TSP_acc.pdf"),plo,width = 6,height =6,units="in")

2.2.5.2 NSol (with TCC and no interaction)

#st03
dataInput=dataTrial_TSP
dataInput = dataInput %>% filter(sol==1)
dataInput$nSolutions_log =log(dataInput$nSolutions)


logitRandomIntercept = brm2(correct ~ nSolutions_log + phaseT + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput, 
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms, refresh = 0)

tableName='tsp_acc_ns3'
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

2.2.6 IC_expost

dataInput = dataTrial_TSP

# Summarise the data to plot
mean_accuracy = dataInput %>% 
  group_by(instanceNumber, sol, ICexpost, phaseT, nSolutions) %>% 
  summarise(accuracy = mean(correct))
`summarise()` regrouping output by 'instanceNumber', 'sol', 'ICexpost', 'phaseT' (override with `.groups` argument)
ggplot(mean_accuracy,aes(x = ICexpost, y = accuracy))+
  geom_point() +
  theme_light() +
  stat_smooth(formula =  y ~ I(x^0.01), method="lm", se= FALSE)+
  xlab("IC_expost")+
  ylab("Human Accuracy")

2.2.6.1 All instances

model_ICexpost = brm2(correct ~ ICexpost + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0)

tableName='tsp_acc_icexpost'
save_summarise_model(model_ICexpost, tableName)
Model Name already exists!


model_ICexpost = allModels[['tsp_acc_icexpost']]
pp  = plot(conditional_effects(model_ICexpost), plot = TRUE, ask = FALSE)


mean_accuracy$correct= mean_accuracy$accuracy
pp$ICexpost + 
  geom_point(data=mean_accuracy,aes(x = ICexpost, y = correct, col=as.factor(phaseT)),inherit.aes = FALSE)+
  theme_minimal()

# Improving the plot
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

pp_plot = pp$ICexpost
pp_plot$layers[[1]]$geom_params$se = FALSE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_point(data=mean_accuracy,
                               aes(x = ICexpost, y = correct, col=as.factor(sol),
                                   shape=as.factor(phaseT), size=2.5), inherit.aes = FALSE),
                         pp_plot$layers)


plo = pp_plot +
  xlab("Instance Complexity (IC)")+#expression(IC[expost]))+
  ylab("Human Performance")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))+
  ylim(0.2,1)

plo
ggsave(paste0(folderOut_figures,"/IC_TSP_acc.pdf"),plo,width = 6,height =6,units="in")

2.2.6.1.1 Model Fit
#st05
dataInput = dataTrial_TSP

# Make predictions excluding random effects (pID)
predictions = predict(model_ICexpost,dataInput, re_formula = NA)


# Estimating the significance of the fit. This is done considering the probability estimation rather than the binary classification.

#Performs the Hosmer-Lemeshow goodness of fit test
logistic_significance = generalhoslem::logitgof(dataInput$correct, predictions[,1], g = 10, ord = FALSE)
At least one cell in the expected frequencies table is < 1. Chi-square approximation may be incorrect.
logistic_significance

    Hosmer and Lemeshow test (binary model)

data:  dataInput$correct, predictions[, 1]
X-squared = 23.813, df = 8, p-value = 0.002463
# Finds R2 using binary outcomes
# https://stackoverflow.com/questions/40901445/function-to-calculate-r2-r-squared-in-r
#predictions = predict(model_ICexpost,dataInput, re_formula = NA)
r_2_binary = cor(dataInput$correct, predictions[,1])^2
r_2_binary
[1] 0.1659575
# Finds R2 using mean accuracies per instance
predictions2 = predict(model_ICexpost,mean_accuracy, re_formula = NA)
r_2_probabilities = cor(mean_accuracy$accuracy, predictions2[,1])^2
r_2_probabilities
[1] 0.7416523

2.2.6.2 Unsatisfiable instances

dataInput = dataTrial_TSP
dataInput = dataInput %>% filter(sol==0)
model_ICexpost = brm2(correct ~ ICexpost + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0)

tableName='tsp_acc_icexpost2'
save_summarise_model(model_ICexpost, tableName)
Model Name already exists!

#st05
dataInput = dataTrial_TSP %>% filter(sol==0)

model_ICexpost = allModels[['tsp_acc_icexpost2']]
# Make predictions excluding random effects (pID)
predictions = predict(model_ICexpost,dataInput, re_formula = NA)

# Estimating the significance of the fit. This is done considering the probability estimation rather than the binary classification.

#Performs the Hosmer-Lemeshow goodness of fit test
logistic_significance = generalhoslem::logitgof(dataInput$correct, predictions[,1], g = 10, ord = FALSE)
At least one cell in the expected frequencies table is < 1. Chi-square approximation may be incorrect.
logistic_significance

    Hosmer and Lemeshow test (binary model)

data:  dataInput$correct, predictions[, 1]
X-squared = 37.059, df = 8, p-value = 1.123e-05
# Finds R2 using binary outcomes
# https://stackoverflow.com/questions/40901445/function-to-calculate-r2-r-squared-in-r
#predictions = predict(model_ICexpost,dataInput, re_formula = NA)
r_2_binary = cor(dataInput$correct, predictions[,1])^2
r_2_binary
[1] 0.1382572
# Finds R2 using mean accuracies per instance

mean_accuracy_unsat = mean_accuracy %>% filter(sol==0)
predictions2 = predict(model_ICexpost,mean_accuracy_unsat, re_formula = NA)
r_2_probabilities = cor(mean_accuracy_unsat$accuracy, predictions2[,1])^2
r_2_probabilities
[1] 0.7899152

2.3 Time Spent

The default data used in this section is dataTrial_TSP_Time. This dataset excludes those participants that never skipped to answer submission.

We first calculate some summary stats for the whole data set (dataTrial_TSP) and see how many participants were excluded in dataTrial_TSP_Time.

2.3.0.1 SummStats TSP

#Summary Stats for Decision Problem
dataInput=dataTrial_TSP

timeSummary = dataInput %>% group_by(pID) %>% summarise(acc=mean(timeSpent)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))

summarise() ungrouping output (override with .groups argument)

kable(timeSummary, digits=1, caption = "Time Summary")

Time Summary
mean min max SD
32.2 19.9 39.2 5.2


yesNoProportions = dataInput %>% group_by(sol,pID) %>% summarise(acc=mean(timeSpent)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))

summarise() regrouping output by ‘sol’ (override with .groups argument) summarise() ungrouping output (override with .groups argument)

kable(yesNoProportions, digits=1, caption = "Time Spent By Solution")

Time Spent By Solution
sol mean min max SD
0 34.1 20.0 40.0 5.9
1 30.2 19.9 38.5 5.2


hist(dataInput$timeSpent,breaks=40)

all_pIDs = unique(dataTrial_TSP$pID)
pIDs_not_in_Time = all_pIDs[!(all_pIDs %in% unique(dataTrial_TSP_Time$pID))]
print(paste0("The participants removed in the TIME df are ", length(pIDs_not_in_Time)))
[1] "The participants removed in the TIME df are 0"
obs_removed = nrow(dataTrial_TSP)-nrow(dataTrial_TSP_Time)
print(paste0("The number of observations removed in the TIME df is ", obs_removed))
[1] "The number of observations removed in the TIME df is 0"

2.3.0.2 SummStats TSP_Time

#Summary Stats for Decision Problem
dataInput=dataTrial_TSP_Time

timeSummary = dataInput %>% group_by(pID) %>% summarise(acc=mean(timeSpent)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))

summarise() ungrouping output (override with .groups argument)

kable(timeSummary, digits=1, caption = "Time Summary")

Time Summary
mean min max SD
32.2 19.9 39.2 5.2


yesNoProportions = dataInput %>% group_by(sol,pID) %>% summarise(acc=mean(timeSpent)) %>% summarise(mean=mean(acc),min=min(acc),max=max(acc),SD=sd(acc))

summarise() regrouping output by ‘sol’ (override with .groups argument) summarise() ungrouping output (override with .groups argument)

kable(yesNoProportions, digits=1, caption = "Time Spent By Solution")

Time Spent By Solution
sol mean min max SD
0 34.1 20.0 40.0 5.9
1 30.2 19.9 38.5 5.2


hist(dataInput$timeSpent,breaks=40)

2.3.0.3 Trial Number and Time Spent

#Trial (experience effect) effect on timeSpent
dataInput=dataTrial_TSP_Time
dataInput$totalTrial = dataInput$block * dataInput$trial

summaryByBlock = dataInput %>% group_by(block,pID) %>% summarise(time=mean(timeSpent)) %>% summarise(mean=mean(time),min=min(time),max=max(time),SD=sd(time))
`summarise()` regrouping output by 'block' (override with `.groups` argument)
`summarise()` ungrouping output (override with `.groups` argument)
kable(summaryByBlock,digits=2 , caption="Time Spent per Trial segregated By Block")

Time Spent per Trial segregated By Block
block mean min max SD
1 33.77 20.29 40.00 4.89
2 32.31 20.38 40.00 5.71
3 30.42 19.10 37.74 5.72


#Regression
linearRandomIntercept = brm2(timeSpent_pct | cens(censored_time) ~ totalTrial+ (1|pID),
                            data=dataInput, 
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms, refresh = 0, iter = iters_high)


tableName='tsp_time_01_r'
save_summarise_model(linearRandomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

2.3.1 TCC

dataInput=dataTrial_TSP_Time %>% group_by(phaseT,pID)%>%summarise(timeSpent1=mean(timeSpent))%>%
  ungroup()%>%group_by(phaseT)%>%summarise(timeSpent=mean(timeSpent1),se=se(timeSpent1))%>%ungroup()
`summarise()` regrouping output by 'phaseT' (override with `.groups` argument)
`summarise()` ungrouping output (override with `.groups` argument)
dataInput$phaseT = recode(dataInput$phaseT, '0' = "Low IC", '1' = "High IC")

plo= ggplot(data=dataInput, aes(y=timeSpent, x=as.factor(phaseT),label = round(timeSpent,digits = 1))) +
  geom_bar(stat = "identity")+
  geom_errorbar(aes(ymin=timeSpent-se, ymax=timeSpent+se), width=.1)+
  #geom_signif(comparisons = list(c("Low IC","High IC")), annotations="***", y_position = 0.95, tip_length = 0.03)+
  labs(title="Time Spent In and Out of phase Transition",x="Instance complexity",y="Time Spent")+
  #coord_cartesian(ylim = c(0.5,1))+
  geom_text(hjust=0.5,vjust = 5, colour="white")+
  theme_light()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),plot.title = element_text(hjust = 0.5))

outputName = "tsp_time_02_g"
plotExport(plo,outputName,folderOut_figures)
[1] "tsp_time_02_g"
quartz_off_screen 
                2 

#Anova contrast for In/Out Phase transition
dataInput = dataTrial_TSP_Time
anovaModel=aov(timeSpent~phaseT+Error(pID/phaseT),dataInput)
anovaPValue=summary(anovaModel)[[2]][[1]][['Pr(>F)']][[1]]
print(paste("P-value for one way ANOVA:",signif(anovaPValue,digits=3)))

[1] “P-value for one way ANOVA: 1.09e-05”

rm(dataInput)

timeSpent ~ phaseT + (1|pID)

#Logistic Regression for In/Out Phase transition
dataInput= dataTrial_TSP_Time

#logistic with random effects (intercept)
# TTTODO
randomIntercept = brm2(timeSpent | cens(censored_time) ~ phaseT + (1|pID),
                       data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="tsp_time_02_r"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

2.3.1.0.1 Plot TCC
library(forcats)
library(ggpol)
#dataInput = dataTrial_TSP

# dataInput$timeSpent_pct = dataInput$timeSpent/SATTaskMaxTime
# dataInput2 = dataInput %>% 
#   group_by(instanceNumber,phaseT) %>% 
#   summarise(timeSpent_pct=median(timeSpent_pct))

dataInput = dataTrial_TSP_Time %>%
  mutate(region = fct_relevel(region,
                              "Underconstrained", "Phase Transition", "Overconstrained")) %>% 
  mutate(sol= as.factor(sol)) %>% 
  mutate(sol = fct_relevel(sol,"1", "0"))

dataInput$timeSpent_pct = dataInput$timeSpent/TSPTaskMaxTime
dataInput2 = dataInput %>% 
  group_by(instanceNumber,region,sol) %>% 
  summarise(timeSpent_pct=median(timeSpent_pct))
`summarise()` regrouping output by 'instanceNumber', 'region' (override with `.groups` argument)
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7


plo = ggplot(dataInput2,aes(x=region,y=timeSpent_pct,fill=sol))+
  # geom_boxjitter(aes(fill=region),jitter.color = NA,jitter.shape = 21)+
  geom_boxjitter(jitter.color = NA,jitter.shape = 21,
                 jitter.params = list(height=0,seed=10),
                 outlier.shape= NA)+
                 #,outlier.shape = 4, outlier.size=0.9)+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0.5))+
  scale_fill_manual(name  ="Region",
                    breaks=c("1","0"),
                    labels=c("Satisfiable","Unsatisfiable"),
                    values=c("#90BE6D","#F94144"))+
  xlab("Typical Case Complexity (TCC)")+
  ylab("Time-on-task")+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))+
  ylim(0.15,1)

plo
ggsave(paste0(folderOut_figures,"/TCC_TSP_time.pdf"),plo,width = 7,height =6,units="in")

2.3.2 Satisfiability and TCC


dataInput=dataTrial_TSP_Time %>% group_by(phaseT,sol,pID)%>%summarise(timeSpent1=mean(timeSpent))%>%ungroup()%>%group_by(sol,phaseT)%>%summarise(timeSpent=mean(timeSpent1),se=se(timeSpent1))%>%ungroup()
`summarise()` regrouping output by 'phaseT', 'sol' (override with `.groups` argument)
`summarise()` regrouping output by 'sol' (override with `.groups` argument)
sol_names <- c(
                    `0` = "Correct answer: NO",
                    `1` = "Correct answer: YES",
                    `2` = "If this is here it means data not filtered"
                    )

plo=ggplot(data=dataInput, aes(y=timeSpent, x=as.factor(as.logical(phaseT)), 
                               label = round(timeSpent,digits = 1),group=1)) +
  geom_line()+
  geom_errorbar(aes(ymin=timeSpent-se, ymax=timeSpent+se), width=.1) +
  geom_point(shape=21, size=3, fill="white")+
  labs(title="Time Spent segregated by solvanbility",x="In Phase Transition?",y="Time Spent")+
  theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(angle=0,hjust=0.5))+
  geom_text(hjust=-0.5, colour="black")+
  facet_grid(.~sol, labeller = as_labeller(sol_names))

outputName = "tsp_time_03_g"
plotExport(plo,outputName,folderOut_figures)
[1] "tsp_time_03_g"
quartz_off_screen 
                2 

timeSpent ~ phaseT + sol + phaseT:sol + (1|pID)

dataInput= dataTrial_TSP_Time
#logistic with random effects (intercept)

dataInput$phaseT = as.factor(dataInput$phaseT)
dataInput$sol = as.factor(dataInput$sol)

# TTTODO
randomIntercept = brm2(timeSpent_pct | cens(censored_time) ~ phaseT + sol + phaseT:sol + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms,
                      refresh = 0, iter = iters_high)

tableName="tsp_time_03_r"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

Margianl Effects

#marginal_effects(randomIntercept)
plot(marginal_effects(allModels[["tsp_time_03_r"]]), plot = TRUE, ask = FALSE)
Method 'marginal_effects' is deprecated. Please use 'conditional_effects' instead.

2.3.3 Satisfiability

#st06
dataInput= dataTrial_TSP_Time
#logistic with random effects (intercept)
#dataInput$sol =as.factor(dataInput$sol)

randomIntercept = brm2(timeSpent_pct | cens(censored_time) ~ sol + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="tsp_time_03_r_B"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

2.3.4 Region effect on time-on-task (Constrainedness)

dataInput=dataTrial_TSP_Time 

dataInput2=dataInput %>% group_by(region,pID)%>%summarise(timeSpent1=mean(timeSpent))%>%ungroup()%>%group_by(region)%>%summarise(timeSpent=mean(timeSpent1),se=se(timeSpent1))%>%ungroup()
`summarise()` regrouping output by 'region' (override with `.groups` argument)
`summarise()` ungrouping output (override with `.groups` argument)
dataInput2$region <- factor(dataInput2$region, levels = c('Underconstrained',
                                                          'Phase Transition',
                                                          'Overconstrained'))

plo= ggplot(data=dataInput2, aes(y=timeSpent, x=region, label = round(timeSpent,digits = 1))) +
  geom_bar(stat = "identity")+
  geom_errorbar(aes(ymin=timeSpent-se, ymax=timeSpent+se), width=.1)+
  labs(title="time Spent by region",x="Region",y="time Spent")+
  geom_text(hjust=0.5,vjust = 5, colour="white") +
  theme_light()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),plot.title = element_text(hjust = 0.5))

outputName = "tsp_time_04_g"
plotExport(plo,outputName,folderOut_figures)
[1] "tsp_time_04_g"
quartz_off_screen 
                2 

#Stats test for time in and out of phase transition: ANOVA
dataInput$overConstrained= (dataInput$region=='Overconstrained')
dataInput$underConstrained= (dataInput$region=='Underconstrained')
randomIntercept = brm2(timeSpent_pct | cens(censored_time) ~ overConstrained + underConstrained + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="tsp_time_04_g_A"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

Is there a difference between time-on-task between overconstrained and the underconstrained region?

fit = hypothesis(allModels[["tsp_time_04_g_A"]],"overConstrainedTRUE=underConstrainedTRUE", seed=seed_brms)
print(fit)
Hypothesis Tests for class b:
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
hdi(fit$samples,ci=0.95)
# Highest Density Interval

Parameter |      95% HDI
------------------------
H1        | [0.14, 0.21]

2.3.5 Number of solution witnesses that satisfy the xonstraints

dataInput=dataTrial_TSP_Time

#Plots nSolutions (x) vs. Accuracy (y)
dataInput3 = dataInput %>% group_by(nSolutions,pID,phaseT)%>%summarise(timeSpent1=mean(timeSpent))%>%ungroup()%>%group_by(nSolutions,phaseT)%>%summarise(timeSpent=mean(timeSpent1),se=se(timeSpent1))%>%ungroup()
`summarise()` regrouping output by 'nSolutions', 'pID' (override with `.groups` argument)
`summarise()` regrouping output by 'nSolutions' (override with `.groups` argument)
dataInput3$sol = dataInput3$nSolutions>=1
dataInput3$phaseT = recode(dataInput3$phaseT, '0' = "Low IC", '1' = "High IC")

dataInput3$nSolutions = dataInput3$nSolutions +1 

plo= ggplot(data=dataInput3, aes(y=timeSpent, x=nSolutions)) +
  geom_errorbar(aes(ymin=timeSpent-se, ymax=timeSpent+se), width=.1)+
  geom_point(shape=23, size=3, fill="red")+
  labs(title="Time Spent and the Number of Solutions",
       x="Number of   Solutions",y="Time Spent")+
  #coord_cartesian(ylim = c(0.5,1))+
  theme_light()+
  scale_x_log10()+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0.5),strip.text.x = element_blank())+
  facet_grid(phaseT~sol, scales = "free_x", space = "free_x")+
  geom_smooth(data=dataInput3, aes(y=timeSpent, x=nSolutions),method=glm,
              se=FALSE,fullrange=TRUE,linetype = "dashed")

outputName = "tsp_nsols_time_g"
plotExport(plo,outputName,folderOut_figures)
[1] "tsp_nsols_time_g"
quartz_off_screen 
                2 

dataInput=dataTrial_TSP_Time

dataInput = dataInput %>% filter(sol==1)
dataInput$nSolutions_log = log(dataInput$nSolutions)

linRandomIntercept = brm2(timeSpent_pct | cens(censored_time) ~ phaseT + nSolutions_log + phaseT:nSolutions_log + (1|pID),
                         data=dataInput,
                         chains=chains_brms,
                         cores = cores_brms,
                         seed=seed_brms, refresh = 0, iter = iters_high)

tableName="tsp_nsols_time_r"
save_summarise_model(linRandomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

This calculates the significance of the number of witnesses beta(slope) for instance with high TCC.

#This version recodes phaseT to OutphaseT, to 

fit = hypothesis(allModels[["tsp_nsols_time_r"]],"nSolutions_log + phaseT:nSolutions_log = 0", seed=seed_brms)

print(fit)
Hypothesis Tests for class b:
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.
hdi(fit$samples,ci=0.95)
# Highest Density Interval

Parameter |        95% HDI
--------------------------
H1        | [-0.03, -0.01]

Marginal Effects

#marginal_effects(randomIntercept)
plot(marginal_effects(allModels[["tsp_nsols_time_r"]]), plot = TRUE, ask = FALSE)
Method 'marginal_effects' is deprecated. Please use 'conditional_effects' instead.

2.3.5.1 No. of witnesses (Regressed alone)

#st07
dataInput= dataTrial_TSP_Time
dataInput = dataInput %>% filter(sol==1)
#logistic with random effects (intercept)
#dataInput$sol =as.factor(dataInput$sol)
dataInput$nSolutions_log = log(dataInput$nSolutions)

randomIntercept = brm2(timeSpent_pct | cens(censored_time) ~  nSolutions_log + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="tsp_nsols_time_r_B"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.


#dataInput3
mean_acc = dataInput %>% group_by(instanceNumber,nSolutions,nSolutions_log, sol,phaseT) %>%
  summarise(accuracy=mean(correct),
            timeSpent_med =median(timeSpent)) 
`summarise()` regrouping output by 'instanceNumber', 'nSolutions', 'nSolutions_log', 'sol' (override with `.groups` argument)
logitRandomIntercept = allModels[['tsp_nsols_time_r_B']]
pp  = plot(conditional_effects(logitRandomIntercept), plot = FALSE, ask = FALSE)

pp$nSolutions + 
  geom_point(data=mean_acc,aes(x = nSolutions_log, y = timeSpent_med/TSPTaskMaxTime),inherit.aes = FALSE)

NA
NA
# Improving the plot

dataInput$nSolutions_log_bin = cut_width(dataInput$nSolutions_log, width=1, boundary =0,labels=FALSE)
dataInput$nSolutions_log_bin = (dataInput$nSolutions_log_bin*1)-0.5

size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

pp_plot = pp$nSolutions_log
pp_plot$layers[[1]]$geom_params$se = FALSE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_boxplot(data=dataInput,
                                      aes(x = nSolutions_log_bin, 
                                          group = nSolutions_log_bin, 
                                          y = timeSpent_pct), 
                                      inherit.aes = FALSE,width=0.7),
                        geom_point(data=mean_acc, 
                                   aes(x = nSolutions_log, y = timeSpent_med/TSPTaskMaxTime,
                                       col=as.factor(sol), shape=as.factor(phaseT), size=2.5),
                                   inherit.aes = FALSE),
                         pp_plot$layers)

plo = pp_plot +
  xlab("Number of solution Witnesses")+#expression(IC[expost]))+
  ylab("Time-on-task")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+#c( "#FC4E07","#E7B800")
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  ylim(0, 1)+
  scale_x_continuous(breaks = c(log(1),log(10),log(100),log(1000),log(10000)),
                     limits =c(0,NA),labels = c("1","10","100","1000","10000") )+
  guides(shape = guide_legend(override.aes = list(size = 3)))

plo
ggsave(paste0(folderOut_figures,"/Nwit_TSP_time.pdf"),plo,width = 6,height =6,units="in")

# Improving the plot
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

pp_plot = pp$nSolutions_log
pp_plot$layers[[1]]$geom_params$se = TRUE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_point(data=dataInput,
                               aes(x = nSolutions_log, y = timeSpent_pct,
                                   shape=as.factor(phaseT), size=0.4,
                                   alpha = 0.5),
                                   inherit.aes = FALSE),
                    geom_jitter(data=mean_acc, 
                                   aes(x = nSolutions_log, 
                                       y = timeSpent_med/TSPTaskMaxTime,
                                       col=as.factor(sol),
                                       shape=as.factor(phaseT), size=2.5),
                                   inherit.aes = FALSE),
                         pp_plot$layers)

plo = pp_plot +
  xlab("Number of solution Witnesses")+#expression(IC[expost]))+
  ylab("Time-on-task")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+#c( "#FC4E07","#E7B800")
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  # ylim(0, 1.1)+
  scale_y_continuous(breaks = c(0,0.25,0.5,0.75,1),limits =c(0,1.1))+
  scale_x_continuous(breaks = c(log(1),log(10),log(100),log(1000),log(10000)),
                     limits =c(log(2),NA),labels = c("1","10","100","1000","10000") )+
  guides(shape = guide_legend(override.aes = list(size = 3)))

plo
ggsave(paste0(folderOut_figures,"/Nwit_TSP_time2.pdf"),plo,width = 6,height =6,units="in")

2.3.6 IC_expost

dataInput = dataTrial_TSP_Time

# Summarise the data to plot
mean_accuracy_time = dataInput %>% 
  group_by(instanceNumber, sol, ICexpost, phaseT, nSolutions) %>% 
  summarise(accuracy = mean(correct), 
            timeSpent_med = median(timeSpent),
            timeSpent = mean(timeSpent))
`summarise()` regrouping output by 'instanceNumber', 'sol', 'ICexpost', 'phaseT' (override with `.groups` argument)
ggplot(mean_accuracy_time,aes(x = ICexpost, y = timeSpent))+
  geom_point() +
  theme_light() +
  stat_smooth(formula =  y ~ I(x^0.01), method="lm", se= FALSE)+
  xlab("IC_expost")+
  ylab("Time Spent")

model_ICexpost = brm2(timeSpent_pct | cens(censored_time) ~ ICexpost + (1|pID),
                           data=dataInput,
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms,
                           refresh = 0, iter = iters_high)

tableName='tsp_time_icexpost'
save_summarise_model(model_ICexpost, tableName)
Model Name already exists!Results may not be meaningful for censored models.Results may not be meaningful for censored models.Results may not be meaningful for censored models.

mean_accuracy_time$correct= mean_accuracy_time$accuracy

model_ICexpost = allModels[['tsp_time_icexpost']]
pp  = plot(conditional_effects(model_ICexpost), plot = FALSE, ask = FALSE)

dataInput$ICexpost_bin = cut_width(dataInput$ICexpost, width=0.02, boundary =0,labels=FALSE)
dataInput$ICexpost_bin = (dataInput$ICexpost_bin*0.02)-0.01

pp_plot = pp$ICexpost

pp_plot$layers <- c(geom_point(data=mean_accuracy_time,
                                   aes(x = ICexpost, y = timeSpent_med/TSPTaskMaxTime),
                                   inherit.aes = FALSE),
                         pp_plot$layers)

pp_plot

pp_plot = pp$ICexpost

pp_plot$layers[[1]]$geom_params$se = TRUE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_point(data=dataInput,
                               aes(x = ICexpost, y = timeSpent_pct,
                                   shape=as.factor(phaseT), size=0.4,
                                   #col=as.factor(sol),
                                   alpha = 0.3),
                                   inherit.aes = FALSE),
                    geom_jitter(data=mean_accuracy_time, 
                                   aes(x = ICexpost, 
                                       y = timeSpent_med/TSPTaskMaxTime,
                                       col=as.factor(sol),
                                       shape=as.factor(phaseT), size=2.5),
                                   inherit.aes = FALSE),
                         pp_plot$layers)

size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

plo = pp_plot +
  xlab("Instance Complexity (IC)")+#expression(IC[expost]))+
  ylab("Time-on-task")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+#c( "#FC4E07","#E7B800")
  # scale_shape_manual(name="IC",values = c(2, 8))+
  # scale_color_manual(name="Solution",values = c("red", "blue"))+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  scale_y_continuous(breaks = c(0,0.25,0.5,0.75,1),limits =c(0,1.1))+
  guides(shape = guide_legend(override.aes = list(size = 3)))

plo
ggsave(paste0(folderOut_figures,"/IC_TSP_time1.pdf"),plo,width = 6,height =6,units="in")

2.4 Time-on-task and accuracy


dataInput= dataTrial_TSP_Time %>% group_by(correct,pID) %>% summarise(timeSpentMeans=mean(timeSpent)) %>% ungroup() %>% group_by(correct) %>%
  summarise(time=mean(timeSpentMeans),se=se(timeSpentMeans))%>%ungroup()
`summarise()` regrouping output by 'correct' (override with `.groups` argument)
`summarise()` ungrouping output (override with `.groups` argument)
plo = ggplot(data=dataInput, aes(y=time, x=as.factor(as.logical(correct)), label = round(time,digits = 2),group=1)) +
  geom_line()+
  geom_errorbar(aes(ymin=time-se, ymax=time+se), width=.1) +
  geom_point(shape=21, size=3, fill="white")+
  labs(title="Time Spent on Correct/Incorrect instances",x="Answer Correct?",y="Time Spent") +
  theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(angle=0,hjust=0.5))+
  geom_text(hjust=-0.5, colour="black")

outputName = "tsp_time_08_g_B"
plotExport(plo,outputName,folderOut_figures)
[1] "tsp_time_08_g_B"
quartz_off_screen 
                2 

correct ~ timeSpent + (1|pID)

dataInput = dataTrial_TSP_Time
#Stats test for time in and out of phase transition: ANOVA
anovaModel=aov(timeSpent~correct+Error(pID/correct),dataInput)
anovaPValue=summary(anovaModel)[[2]][[1]][['Pr(>F)']][[1]]
print(paste("P-value for one way ANOVA:",signif(anovaPValue,digits=3)))
[1] "P-value for one way ANOVA: 4.43e-08"
#Stats test for time for correct/incorrect answers
logitRandomIntercept = brm2(correct ~ timeSpent_pct + (1|pID),
                           family=bernoulli(link="logit"),
                           data=dataInput, 
                           chains=chains_brms,
                           cores = cores_brms,
                           seed=seed_brms, refresh = 0)

tableName="tsp_time_08_r_B"
save_summarise_model(logitRandomIntercept, tableName)
Model Name already exists!

Marginal Effects {#tsp_time_acc}

plot(marginal_effects(allModels[["tsp_time_08_r_B"]]), plot = TRUE, ask = FALSE)
Method 'marginal_effects' is deprecated. Please use 'conditional_effects' instead.

2.5 Number of Clicks

2.5.0.1 Satisfiability

dataInput=dataTrial_TSP_clicks

# BOXPLOT
plo= ggplot(data=dataInput, aes(y=n_clicks, x=region, label = round(n_clicks,digits = 0))) +
  geom_boxplot()+
  labs(x="Region",y="n_clicks")+
  #coord_cartesian(ylim = c(0.5,1))+
  geom_text(hjust=0.5,vjust = 5, colour="white") +
  theme_light()+
  theme(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(),plot.title = element_text(hjust = 0.5))+
  facet_grid(.~sol)


outputName = 'tsp_clicks_00_g'
plotExport(plo,outputName,folderOut_figures)
[1] "tsp_clicks_00_g"
quartz_off_screen 
                2 

size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

dataInput2 = dataTrial_TSP_clicks %>% 
  mutate(region = fct_relevel(region,
                              "Underconstrained", "Phase Transition", "Overconstrained"))%>% 
  mutate(sol= as.factor(sol)) %>% 
  mutate(sol = fct_relevel(sol,"1", "0"))

dataInput3 = dataInput2 %>% 
  group_by(instanceNumber,region,sol) %>% 
  summarise(n_clicks=mean(n_clicks))
`summarise()` regrouping output by 'instanceNumber', 'region' (override with `.groups` argument)
plo = ggplot(dataInput3,aes(x=region,y=n_clicks,fill=sol))+
  # geom_boxjitter(aes(fill=region),jitter.color = NA,jitter.shape = 21)+
  geom_boxjitter(jitter.color = NA,jitter.shape = 21,
                 jitter.params = list(height=0,seed=10),
                 outlier.shape= NA)+
                 #,outlier.shape = 4, outlier.size=0.9)+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        plot.title = element_text(hjust = 0.5))+
  scale_fill_manual(name  ="Region",
                    breaks=c("1","0"),
                    labels=c("Satisfiable","Unsatisfiable"),
                    values=c("#90BE6D","#F94144"))+
  xlab("Typical Case Complexity (TCC)")+
  ylab("Number of clicks")+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))+
  ylim(20,30)


plo
ggsave(paste0(folderOut_figures,"/TCC_TSP_nclicks.pdf"),plo,width = 7,height =6,units="in")

#Logistic Regression for In/Out Phase transition
dataInput= dataTrial_TSP_clicks

#logistic with random effects (intercept)
# TTTODO
randomIntercept = brm2(n_clicks ~ sol + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="tsp_clicks_01_r"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!

2.5.0.2 TCC

#Logistic Regression for In/Out Phase transition
dataInput= dataTrial_TSP_clicks

#logistic with random effects (intercept)
# TTTODO
randomIntercept = brm2(n_clicks ~ phaseT + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="tsp_clicks_02_r"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!

2.5.0.2.1 And satisfiability
#Logistic Regression for In/Out Phase transition
dataInput= dataTrial_TSP_clicks

#logistic with random effects (intercept)
# TTTODO
randomIntercept = brm2(n_clicks ~ region+ (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="tsp_clicks_02B_r"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!

#Logistic Regression for In/Out Phase transition
dataInput= dataTrial_TSP_clicks

#logistic with random effects (intercept)
# TTTODO
dataInput$phaseT = as.factor(dataInput$phaseT)
dataInput$sol = as.factor(dataInput$sol)
randomIntercept = brm2(n_clicks ~ phaseT + sol + phaseT:sol + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="tsp_clicks_02C_r"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!

pp  = plot(conditional_effects(allModels[["tsp_clicks_02C_r"]]), plot = TRUE, ask = FALSE)

# stche
model = allModels[['tsp_clicks_02C_r']]

fit = hypothesis(model,"sol1 + phaseT1:sol1=0", seed=seed_brms)

print(fit)
Hypothesis Tests for class b:
---
'CI': 90%-CI for one-sided and 95%-CI for two-sided hypotheses.
'*': For one-sided hypotheses, the posterior probability exceeds 95%;
for two-sided hypotheses, the value tested against lies outside the 95%-CI.
Posterior probabilities of point hypotheses assume equal prior probabilities.

2.5.0.3 ICexpost

#Logistic Regression for In/Out Phase transition
dataInput= dataTrial_TSP_clicks

#logistic with random effects (intercept)
# TTTODO
randomIntercept = brm2(n_clicks ~ ICexpost + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="tsp_clicks_03_r"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!

pp  = plot(conditional_effects(allModels[["tsp_clicks_03_r"]]), plot = TRUE, ask = FALSE)

dataInput= dataTrial_TSP_clicks
# Summarise the data to plot
mean_nclicks = dataInput %>% 
  group_by(instanceNumber, sol, ICexpost, phaseT, nSolutions) %>% 
  summarise(n_clicks = median(n_clicks))
`summarise()` regrouping output by 'instanceNumber', 'sol', 'ICexpost', 'phaseT' (override with `.groups` argument)
model_ICexpost = allModels[["tsp_clicks_03_r"]]
pp  = plot(conditional_effects(model_ICexpost), plot = FALSE, ask = FALSE)

pp$ICexpost +
  geom_point(data=mean_nclicks,aes(x = ICexpost, y =n_clicks),inherit.aes = FALSE)

# Improving the plot
# Improving the plot
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

pp_plot = pp$ICexpost
pp_plot$layers[[1]]$geom_params$se = FALSE
pp_plot$layers[[1]]$aes_params$colour="#577590"



pp_plot$layers <- c(geom_jitter(data=dataInput,
                               aes(x = ICexpost, y = n_clicks,
                                   shape=as.factor(phaseT)), size=0.7,
                                   alpha = 0.3,
                                   inherit.aes = FALSE,height=0.2),
                    geom_point(data=mean_nclicks, 
                                   aes(x = ICexpost, y = n_clicks,
                                       col=as.factor(sol), shape=as.factor(phaseT)),size=2.5,
                                   inherit.aes = FALSE),
                         pp_plot$layers)

plo = pp_plot +
  xlab("Instance Complexity (IC)")+#expression(IC[expost]))+
  ylab("Number of Clicks")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  ylim(10,50)
#+  guides(shape = guide_legend(override.aes = list(size = 3)))

# Justification to reduce range to 10-50
sum(between(dataTrial_TSP_clicks$n_clicks,10,50))/length(dataTrial_TSP_clicks$n_clicks)
[1] 0.9873016
plo
ggsave(paste0(folderOut_figures,"/IC_TSP_nclicks.pdf"),plo,width = 6,height =6,units="in")

2.5.0.3.1 And satisfiability
#Logistic Regression for In/Out Phase transition
dataInput= dataTrial_TSP_clicks

#logistic with random effects (intercept)
# TTTODO
randomIntercept = brm2(n_clicks ~ ICexpost + sol + ICexpost:sol + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="tsp_clicks_03_rB"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!

#Logistic Regression for In/Out Phase transition
dataInput= dataTrial_TSP_clicks

#logistic with random effects (intercept)
# TTTODO
randomIntercept = brm2(n_clicks ~ ICexpost + sol + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="tsp_clicks_03_rC"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!

pp  = plot(conditional_effects(allModels[["tsp_clicks_03_rC"]]), plot = TRUE, ask = FALSE)

2.5.0.4 Number of witnesses

Only Satisfiable instances:

dataInput= dataTrial_TSP_clicks %>% filter(sol==1)

dataInput$nSolutions_log = log(dataInput$nSolutions)
#logistic with random effects (intercept)
# TTTODO
randomIntercept = brm2(n_clicks ~ nSolutions_log + (1|pID),
                      data=dataInput, 
                      chains=chains_brms,
                      cores = cores_brms,
                      seed=seed_brms, refresh = 0, iter = iters_high)

tableName="tsp_clicks_04_rB"
save_summarise_model(randomIntercept, tableName)
Model Name already exists!

#dataInput = dataTrial_SAT_clicks
# Summarise the data to plot
mean_nclicks = dataInput %>% 
  group_by(instanceNumber, sol, ICexpost, phaseT, nSolutions_log) %>% 
  summarise(n_clicks = median(n_clicks))
`summarise()` regrouping output by 'instanceNumber', 'sol', 'ICexpost', 'phaseT' (override with `.groups` argument)
model_nsol = allModels[["tsp_clicks_04_rB"]]
pp  = plot(conditional_effects(model_nsol), plot = FALSE, ask = FALSE)

pp$nSolutions_log +
   geom_point(data=mean_nclicks, aes(x = nSolutions_log, y =n_clicks),inherit.aes = FALSE)

# Improving the plot
# Improving the plot
size_big = 20
size_small = 16
size_ss = 10
size_xs = 7

pp_plot = pp$nSolutions
pp_plot$layers[[1]]$geom_params$se = FALSE
pp_plot$layers[[1]]$aes_params$colour="#577590"

pp_plot$layers <- c(geom_jitter(data=dataInput,
                               aes(x = nSolutions_log, y = n_clicks,
                                   shape=as.factor(phaseT)), size=1,
                                   alpha = 0.3,
                                   inherit.aes = FALSE,width=0.2,height =0.2),
                        geom_point(data=mean_nclicks, 
                                   aes(x = nSolutions_log, y = n_clicks,
                                       col=as.factor(sol), shape=as.factor(phaseT)), size=4,
                                   inherit.aes = FALSE),
                         pp_plot$layers)

plo = pp_plot +
  xlab("Number of Solution Witnesses")+
  ylab("Number of Clicks")+
  scale_shape_manual(name="",values = c(17,16)) +
  scale_color_manual(name="",values = c("1"="#90BE6D","0"="#F94144"))+
  theme_classic()+
  theme(axis.title = element_text(size= size_big),
       axis.text=element_text(size=size_small),
       legend.position = "none")+
  guides(shape = guide_legend(override.aes = list(size = 3)))+
  scale_x_continuous(breaks = c(log(1),log(10),log(100),log(1000),log(10000)),
                   limits =c(0,NA),labels = c("1","10","100","1000","10000") )+
  ylim(10,50)

plo

ggsave(paste0(folderOut_figures,"/Nwit_TSP_nclicks.pdf"),
       plo,width = 6,height =6,units="in")

3 Save Models

#saveRDS(allModels,file.path(folderOut,"ICx3_models.RData"))

4 Session Info

sessionInfo()
R version 4.0.2 (2020-06-22)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Catalina 10.15.5

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib

locale:
[1] en_AU.UTF-8/en_AU.UTF-8/en_AU.UTF-8/C/en_AU.UTF-8/en_AU.UTF-8

attached base packages:
[1] parallel  stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] ggpol_0.0.7        forcats_0.5.0      performance_0.4.8  bayestestR_0.8.2  
 [5] see_0.6.2          parameters_0.12.0  tidyr_1.1.1        DiagrammeR_1.0.6.1
 [9] bmlm_1.3.11        bayesplot_1.7.2    sjstats_0.18.0     brms_2.13.5       
[13] Rcpp_1.0.5.2       readr_1.3.1        Hmisc_4.4-1        Formula_1.2-3     
[17] survival_3.1-12    lattice_0.20-41    plotly_4.9.2.1     pander_0.6.3      
[21] ggsignif_0.6.0     knitr_1.29         ggplot2_3.3.2      reshape2_1.4.4    
[25] dplyr_1.0.2       

loaded via a namespace (and not attached):
  [1] backports_1.1.9      plyr_1.8.6           igraph_1.2.5        
  [4] lazyeval_0.2.2       splines_4.0.2        crosstalk_1.1.0.1   
  [7] rstantools_2.1.1     inline_0.3.15        digest_0.6.25       
 [10] htmltools_0.5.0      rsconnect_0.8.16     fansi_0.4.1         
 [13] magrittr_1.5         checkmate_2.0.0      cluster_2.1.0       
 [16] modelr_0.1.8         RcppParallel_5.0.2   matrixStats_0.56.0  
 [19] xts_0.12-0           prettyunits_1.1.1    jpeg_0.1-8.1        
 [22] colorspace_1.4-1     xfun_0.16            callr_3.4.3         
 [25] crayon_1.3.4         jsonlite_1.7.0       lme4_1.1-23         
 [28] zoo_1.8-8            glue_1.4.1           gtable_0.3.0        
 [31] emmeans_1.5.0        sjmisc_2.8.5         V8_3.2.0            
 [34] pkgbuild_1.1.0       rstan_2.21.2         abind_1.4-5         
 [37] scales_1.1.1         mvtnorm_1.1-1        miniUI_0.1.1.1      
 [40] viridisLite_0.3.0    xtable_1.8-4         generalhoslem_1.3.4 
 [43] htmlTable_2.0.1      tmvnsim_1.0-2        foreign_0.8-80      
 [46] stats4_4.0.2         StanHeaders_2.21.0-6 DT_0.15             
 [49] htmlwidgets_1.5.1    httr_1.4.2           threejs_0.3.3       
 [52] lavaan_0.6-8         RColorBrewer_1.1-2   ellipsis_0.3.1      
 [55] farver_2.0.3         pkgconfig_2.0.3      reshape_0.8.8       
 [58] loo_2.3.1            nnet_7.3-14          labeling_0.3        
 [61] tidyselect_1.1.0     rlang_0.4.7          later_1.1.0.1       
 [64] effectsize_0.3.2     visNetwork_2.0.9     munsell_0.5.0       
 [67] tools_4.0.2          cli_2.0.2            generics_0.0.2      
 [70] sjlabelled_1.1.6     broom_0.7.0          ggridges_0.5.2      
 [73] fdrtool_1.2.16       evaluate_0.14        stringr_1.4.0       
 [76] fastmap_1.0.1        yaml_2.2.1           processx_3.4.3      
 [79] purrr_0.3.4          glasso_1.11          pbapply_1.4-3       
 [82] nlme_3.1-148         mime_0.9             compiler_4.0.2      
 [85] shinythemes_1.1.2    rstudioapi_0.11      curl_4.3            
 [88] png_0.1-7            tibble_3.0.3         statmod_1.4.34      
 [91] pbivnorm_0.6.0       stringi_1.4.6        highr_0.8           
 [94] ps_1.3.4             qgraph_1.6.9         Brobdingnag_1.2-6   
 [97] Matrix_1.2-18        psych_2.0.9          nloptr_1.2.2.2      
[100] markdown_1.1         shinyjs_1.1          vctrs_0.3.2         
[103] pillar_1.4.6         lifecycle_0.2.0      bridgesampling_1.0-0
[106] estimability_1.3     corpcor_1.6.9        data.table_1.13.0   
[109] insight_0.13.1       httpuv_1.5.4         R6_2.4.1            
[112] latticeExtra_0.6-29  promises_1.1.1       gridExtra_2.3       
[115] codetools_0.2-16     boot_1.3-25          colourpicker_1.0    
[118] MASS_7.3-51.6        gtools_3.8.2         assertthat_0.2.1    
[121] withr_2.2.0          mnormt_2.0.2         shinystan_2.5.0     
[124] mgcv_1.8-31          hms_0.5.3            grid_4.0.2          
[127] rpart_4.1-15         coda_0.19-3          minqa_1.2.4         
[130] rmarkdown_2.7        lubridate_1.7.9      shiny_1.5.0         
[133] base64enc_0.1-3      dygraphs_1.1.1.6    
LS0tCnRpdGxlOiAiQmVoYXZpb3VyYWwgcmVzdWx0cyBmb3IgdGhlIFRTUCBhbmQgM1NBVCIKYXV0aG9yOiAiSi4gUGFibG8gRnJhbmNvIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiwgJVknKWAiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICB0aGVtZTogdW5pdGVkCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKZWRpdG9yX29wdGlvbnM6CiAgbWFya2Rvd246CiAgICB3cmFwOiA3MgotLS0KCmBgYHtyIGRvY19zZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCmBgYHs9aHRtbH0KPHN0eWxlPgoKdGFibGUsIHRkLCB0aCB7CiAgYm9yZGVyOiBub25lOwogIHBhZGRpbmctbGVmdDogMWVtOwogIHBhZGRpbmctcmlnaHQ6IDFlbTsKICBtaW4td2lkdGg6IDUwJTsKICBtYXJnaW4tbGVmdDogYXV0bzsKICBtYXJnaW4tcmlnaHQ6IGF1dG87CiAgbWFyZ2luLXRvcDogMWVtOwogIG1hcmdpbi1ib3R0b206IDFlbTsKfQoKPC9zdHlsZT4KYGBgCgpgYGB7ciBmb2xkZXJfbWFuYWdlbWVudH0KcHJvamVjdF9mb2xkZXIgPSAiL1ZvbHVtZXMvR29vZ2xlRHJpdmUvTXkgRHJpdmUvTWVsYm91cm5lL1VOSU1FTEIvUmVzZWFyY2gvQ29tcGxleGl0eSBQcm9qZWN0L0lDeDNfbmV3L0NvZGUvYmVoYXZBbmFseXNpcy9JQ3gzX3N1cHAvIgpjb2RlX2ZvbGRlciA9IHBhc3RlMChwcm9qZWN0X2ZvbGRlciwgIkNvZGUvIikKZGF0YV9mb2xkZXIgPSBwYXN0ZTAocHJvamVjdF9mb2xkZXIsICJEYXRhLyIpCgpzZXR3ZChjb2RlX2ZvbGRlcikKa25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSBjb2RlX2ZvbGRlcikKCiNJbXBvcnQgZnVuY3Rpb25zCnNvdXJjZShmaWxlLnBhdGgoY29kZV9mb2xkZXIsIkRlc2NyaXB0aXZlRnVuY3Rpb25zLlIiKSkKCiMgUGFydGljaXBhbnQgRGF0YQpmb2xkZXJNb2RlbHMgPSAiL1ZvbHVtZXMvR29vZ2xlRHJpdmUvTXkgRHJpdmUvTWVsYm91cm5lL1VOSU1FTEIvUmVzZWFyY2gvQ29tcGxleGl0eSBQcm9qZWN0L0lDeDNfbmV3L0NvZGUvYmVoYXZBbmFseXNpcy9PdXRwdXQvIgoKZm9sZGVyT3V0X2ZpZ3VyZXMgPSBwYXN0ZTAocHJvamVjdF9mb2xkZXIsIk91dHB1dC9GaWd1cmVzIikKZm9sZGVyT3V0X3RhYmxlcyA9IHBhc3RlMChwcm9qZWN0X2ZvbGRlciwiT3V0cHV0L1RhYmxlcyIpCgpgYGAKCgpgYGB7cn0KIyBGZWF0dXJlcyBvZiB0aGUgdGFza3MgbmVlZGVkIGZvciB0aGUgYW5hbHlzaXMKU0FUVGFza01heFRpbWU9MTEwCm5WYXJzX3NhdD01ClNBVFRhc2tNYXhDbGlja3MgPSAyMAoKVFNQVGFza01heFRpbWUgPSA0MAoKCiMgQnJtcyBwYXJhbWV0ZXJzCmNoYWluc19icm1zID0gNApjb3Jlc19icm1zID0gbWluKGNoYWluc19icm1zLGRldGVjdENvcmVzKCkpCnNlZWRfYnJtcyA9IDExMQppdGVyc19oaWdoID0gNDAwMApgYGAKCgpgYGB7ciBzZXR1cCwgY29sbGFwc2U9VFJVRX0KIyMgU2V0dGluZyB1cCB0aGUgYmFzaWNzCmxpYnJhcnkoZ2dwbG90MikKI2xpYnJhcnkoc3RhcmdhemVyKQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdnc2lnbmlmKQpsaWJyYXJ5KHBhbmRlcikKbGlicmFyeShwbG90bHkpCmxpYnJhcnkocmVzaGFwZTIpCmxpYnJhcnkoSG1pc2MpCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkoYnJtcykKbGlicmFyeShwYXJhbGxlbCkKbGlicmFyeShzanN0YXRzKQpsaWJyYXJ5KGJheWVzcGxvdCkKbGlicmFyeShibWxtKQpsaWJyYXJ5KERpYWdyYW1tZVIpCmxpYnJhcnkodGlkeXIpCgojRnJvbSBlYXN5c3RhdHM6CmxpYnJhcnkocGFyYW1ldGVycykKbGlicmFyeShzZWUpCmxpYnJhcnkoYmF5ZXN0ZXN0UikKbGlicmFyeShwZXJmb3JtYW5jZSkKCmxpYnJhcnkoZm9yY2F0cykKbGlicmFyeShnZ3BvbCkKYGBgCgpgYGB7cn0KIyBGdW5jdGlvbnMKCnNhdmVfc3VtbWFyaXNlX21vZGVsID0gZnVuY3Rpb24obW9kZWwsIG1vZGVsTmFtZSl7CiAgaWYgKG1vZGVsTmFtZSAlaW4lIG5hbWVzKGFsbE1vZGVscykpewogICAgd2FybmluZygiTW9kZWwgTmFtZSBhbHJlYWR5IGV4aXN0cyEiKQogICAgbW9kZWwgPSBhbGxNb2RlbHNbW21vZGVsTmFtZV1dCiAgfSBlbHNlIHsKICAgIGFsbE1vZGVsc1tbbW9kZWxOYW1lXV08PC0gbW9kZWwKICB9CiAgICB0YWJsZSA9IG1vZGVsX3BhcmFtZXRlcnMobW9kZWwsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaV9tZXRob2QgPSAiSERJIixjaT0wLjk1LHRlc3QgPSBjKCJoZGkiLCJwZCIpKQogICAgCiAgICB0YWJsZTIgPSBwZXJmb3JtYW5jZTo6bW9kZWxfcGVyZm9ybWFuY2UobW9kZWwsbWV0cmljcz0iY29tbW9uIikKCiAgICBwbG8gPSBwbG90KGhkaShtb2RlbCwgY2kgPSBjKDAuOTUpKSwgZGF0YSA9IG1vZGVsKSsKICAgICAgICAgIGdndGl0bGUoIlBvc3RlcmlvciBkaXN0cmlidXRpb25zIiwKICAgICAgICAgICAgICAgICAgIndpdGggbWVkaWFucyBhbmQgOTUlIHF1YW50aWxlLWJhc2VkLWludGVydmFscyIpICsKICAgICAgICAgIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLAogICAgICAgICAgICAgICAgcGxvdC5zdWJ0aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCiAgCiAgICBwcmludChhc190aWJibGUodGFibGUpKQogICAgcHJpbnQoYXNfdGliYmxlKHRhYmxlMikpCiAgICBwcmludChwbG8pCiAgCiAgICAjYWxsTW9kZWxzW1ttb2RlbE5hbWVdXTw8LSBtb2RlbAp9CgpgYGAKCmBgYHtyfQojIFVzZSBjdXJyZW50IG1vZGVscyBvciByZXJ1biBldmVyeXRoaW5nIENvbW1lbnQgb25lIG9wdGlvbgoKIyBhbGxNb2RlbHMgOj0gbGlzdCBvZiBhbGwgdGhlIHJlZ3Jlc3Npb25zIHRoYXQgYXJlIHJ1biAKCgojIyBPcHRpb24xOiBVc2UgY3VycmVudCBzYXZlZCBtb2RlbHMKCiMgSW1wb3J0IGVzdGltYXRlZCBtb2RlbHMKYWxsTW9kZWxzID0gcmVhZF9yZHMoZmlsZS5wYXRoKGZvbGRlck1vZGVscywiSUN4M19tb2RlbHMuUkRhdGEiKSkKCiMgRG9uJ3QgcnVuIGJybXMgbW9kZWxzCmJybTIgPSAgZnVuY3Rpb24oLi4uKXsKICByZXR1cm4oRkFMU0UpCn0KCiMgIyMgT3B0aW9uMjogUmVydW4gZXZlcnl0aGluZyBmcm9tIHNjcmF0Y2gKIyAKIyBhbGxNb2RlbHM9dmVjdG9yKCJsaXN0IiwgbGVuZ3RoPTApCiMgCiMgYnJtMiA9ICBmdW5jdGlvbiguLi4pewojICAgcmV0dXJuKGJybSguLi4pKQojIH0KCmBgYAoKIyBCb29sZWFuIHNhdGlzZmlhYmlsaXR5IHByb2JsZW0gKDNTQVQpCgojIyBGdW5jdGlvbnMKCmBgYHtyfQpjYWxjdWxhdGVfc2F0X0lDZXhwb3N0ID1mdW5jdGlvbihtaW5fY29zdCxuY2xhdXNlcyl7CiAgSUNleHBvc3QgID0gIG1pbl9jb3N0L25jbGF1c2VzCiAgcmV0dXJuKElDZXhwb3N0KQp9CmBgYAoKIyMgQWNjdXJhY3kKClJlYWQgQ2xlYW4gRGF0YSB0byBmaWxlCgpgYGB7cn0KI0ltcG9ydCBTQVQgZGF0YQpkYXRhVHJpYWxfU0FUPSByZWFkX2NzdjIoZmlsZS5wYXRoKGRhdGFfZm9sZGVyLCJTQVRfY2xlYW4uY3N2IikpCgpkYXRhVHJpYWxfU0FUX1RpbWUgPSByZWFkX2NzdjIoZmlsZS5wYXRoKGRhdGFfZm9sZGVyLCJTQVRfY2xlYW5fdGltZS5jc3YiKSkKZGF0YVRyaWFsX1NBVF9UaW1lJHRpbWVTcGVudF9wY3QgPSBkYXRhVHJpYWxfU0FUX1RpbWUkdGltZVNwZW50L1NBVFRhc2tNYXhUaW1lCgpjb2xvcl9zY2hlbWVfc2V0KCJncmVlbiIpCgpkYXRhVHJpYWxfU0FUJGNlbnNvcmVkX3RpbWUgPSBpZmVsc2UoZGF0YVRyaWFsX1NBVCR0aW1lU3BlbnQgPT0gU0FUVGFza01heFRpbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInJpZ2h0Iiwibm9uZSIpCgpkYXRhVHJpYWxfU0FUX1RpbWUkY2Vuc29yZWRfdGltZSA9IGlmZWxzZShkYXRhVHJpYWxfU0FUX1RpbWUkdGltZVNwZW50ID09IFNBVFRhc2tNYXhUaW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyaWdodCIsIm5vbmUiKQoKaW5zdGFuY2VQcm9wZXJ0aWVzX1NBVD0gcmVhZF9yZHMocGFzdGUwKGRhdGFfZm9sZGVyLCJpbnN0YW5jZV9wcm9wZXJ0aWVzX1NBVC5yZHMiKSkKaW5zdGFuY2VQcm9wZXJ0aWVzX1NBVCA9IGluc3RhbmNlUHJvcGVydGllc19TQVQgJT4lIHNlbGVjdChpbnN0YW5jZU51bWJlciwgbWluX2Nvc3QsIG1pbl9tb2RlbCxjb3N0cyxtb2RlbHMsblNvbHV0aW9ucykKCmRhdGFUcmlhbF9TQVQgPSBsZWZ0X2pvaW4oZGF0YVRyaWFsX1NBVCxpbnN0YW5jZVByb3BlcnRpZXNfU0FULCBieSA9ICJpbnN0YW5jZU51bWJlciIpCmRhdGFUcmlhbF9TQVRfVGltZSA9IGxlZnRfam9pbihkYXRhVHJpYWxfU0FUX1RpbWUsaW5zdGFuY2VQcm9wZXJ0aWVzX1NBVCwgYnkgPSAiaW5zdGFuY2VOdW1iZXIiKQoKZGF0YVRyaWFsX1NBVCRJQ2V4cG9zdCA9IGNhbGN1bGF0ZV9zYXRfSUNleHBvc3QoZGF0YVRyaWFsX1NBVCRtaW5fY29zdCxkYXRhVHJpYWxfU0FUJG5DbGF1c2VzKQpkYXRhVHJpYWxfU0FUX1RpbWUkSUNleHBvc3QgPSBjYWxjdWxhdGVfc2F0X0lDZXhwb3N0KGRhdGFUcmlhbF9TQVRfVGltZSRtaW5fY29zdCxkYXRhVHJpYWxfU0FUX1RpbWUkbkNsYXVzZXMpCgojQ0xpY2tzCmRhdGFfU0FUX2NsaWNrcyA9IHJlYWRfY3N2MihmaWxlLnBhdGgoZGF0YV9mb2xkZXIsIlNBVF9jbGlja3MuY3N2IikpCm5DbGlja3MgPSBkYXRhX1NBVF9jbGlja3MgJT4lIGdyb3VwX2J5KHBJRCxibG9jayx0cmlhbCkgJT4lIHN1bW1hcmlzZShuX2NsaWNrcyA9bigpKQoKZGF0YVRyaWFsX1NBVF9jbGlja3M9bWVyZ2UobkNsaWNrcywKICAgICAgICAgICAgICAgICAgZGF0YVRyaWFsX1NBVCwgYnk9YygicElEIiwiYmxvY2siLCJ0cmlhbCIpKQoKZGF0YVRyaWFsX1NBVF9jbGlja3MkY2Vuc29yZWRfY2xpY2tzID0gaWZlbHNlKGRhdGFUcmlhbF9TQVRfY2xpY2tzJG5fY2xpY2tzPT0gU0FUVGFza01heENsaWNrcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmlnaHQiLCJub25lIikKCmBgYAoKYGBge3IsIHJlc3VsdHM9J2FzaXMnfQojU3VtbWFyeSBTdGF0cyBmb3IgRGVjaXNpb24gUHJvYmxlbQpkYXRhSW5wdXQ9ZGF0YVRyaWFsX1NBVAoKYWNjdXJhY3lTdW1tYXJ5ID0gZGF0YUlucHV0ICU+JSBncm91cF9ieShwSUQpICU+JSBzdW1tYXJpc2UoYWNjPW1lYW4oY29ycmVjdCkpICU+JSBzdW1tYXJpc2UobWVhbj1tZWFuKGFjYyksbWluPW1pbihhY2MpLG1heD1tYXgoYWNjKSxTRD1zZChhY2MpKQprYWJsZShhY2N1cmFjeVN1bW1hcnksIGRpZ2l0cz0yLCBjYXB0aW9uID0gIkFjY3VyYWN5IFN1bW1hcnkiKQoKYW5zd2VyU3VtbWFyeSA9IGRhdGFJbnB1dCAlPiUgZ3JvdXBfYnkocElEKSAlPiUgc3VtbWFyaXNlKGFjYz1tZWFuKGFuc3dlcikpICU+JSBzdW1tYXJpc2UobWVhbj1tZWFuKGFjYyksbWluPW1pbihhY2MpLG1heD1tYXgoYWNjKSxTRD1zZChhY2MpKQprYWJsZShhbnN3ZXJTdW1tYXJ5LCBkaWdpdHM9MiwgY2FwdGlvbiA9ICJQcm9wb3J0aW9uIG9mIHRpbWVzIHRoYXQgWUVTIHdhcyBzZWxlY3RlZCBhcyB0aGUgYW5zd2VyIikKCnllc05vUHJvcG9ydGlvbnMgPSBkYXRhSW5wdXQgJT4lIGdyb3VwX2J5KHNvbCxwSUQpICU+JSBzdW1tYXJpc2UoYWNjPW1lYW4oY29ycmVjdCkpICU+JSBzdW1tYXJpc2UobWVhbj1tZWFuKGFjYyksbWluPW1pbihhY2MpLG1heD1tYXgoYWNjKSxTRD1zZChhY2MpKQprYWJsZSh5ZXNOb1Byb3BvcnRpb25zLCBkaWdpdHM9MiwgY2FwdGlvbiA9ICJBY2N1cmFjeSBCeSBTb2x1dGlvbiIpCgpgYGAKCiMjIyBFZmZlY3Qgb2YgVHJpYWwgbnVtYmVyIG9uIGFjY3VyYWN5CgpgYGB7cn0KI1RyaWFsIChleHBlcmllbmNlIGVmZmVjdCkgZWZmZWN0CmRhdGFJbnB1dD1kYXRhVHJpYWxfU0FUCgojU3VtbWFyeQpzdW1tYXJ5QnlCbG9jayA9IGRhdGFJbnB1dCAlPiUgZ3JvdXBfYnkoYmxvY2sscElEKSAlPiUgc3VtbWFyaXNlKGFjYz1tZWFuKGNvcnJlY3QpKSAlPiUgc3VtbWFyaXNlKG1lYW49bWVhbihhY2MpLG1pbj1taW4oYWNjKSxtYXg9bWF4KGFjYyksU0Q9c2QoYWNjKSkKa2FibGUoc3VtbWFyeUJ5QmxvY2ssIGRpZ2l0cz0yLCBjYXB0aW9uID0gIkFjY3VyYWN5IEJ5IEJsb2NrIE51bWJlciIpCgojUmVncmVzc3Npb24KZGF0YUlucHV0JHRvdGFsVHJpYWwgPSBkYXRhSW5wdXQkYmxvY2sgKiBkYXRhSW5wdXQkdHJpYWwKCmxvZ2l0UmFuZG9tSW50ZXJjZXB0ID0gYnJtMihjb3JyZWN0IH4gdG90YWxUcmlhbCsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5PWJlcm5vdWxsaShsaW5rPSJsb2dpdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCkKCnRhYmxlTmFtZT0nc2F0X2FjY18wMV9yJwoKc2F2ZV9zdW1tYXJpc2VfbW9kZWwobG9naXRSYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKCmBgYAoKIyMjIFRDQyBBY2N1cmFjeSBDb250cmFzdAoKYGBge3IgLCBmaWcuYWxpZ249J2NlbnRlcid9CmRhdGFJbnB1dD1kYXRhVHJpYWxfU0FUICU+JSBncm91cF9ieShwaGFzZVQscElEKSU+JXN1bW1hcmlzZShhY2N1cmFjeTE9bWVhbihjb3JyZWN0KSklPiV1bmdyb3VwKCklPiVncm91cF9ieShwaGFzZVQpJT4lc3VtbWFyaXNlKGFjY3VyYWN5PW1lYW4oYWNjdXJhY3kxKSxzZT1zZShhY2N1cmFjeTEpKSU+JXVuZ3JvdXAoKQoKZGF0YUlucHV0JHBoYXNlVCA9IHJlY29kZShkYXRhSW5wdXQkcGhhc2VULCAnMCcgPSAiTG93IElDIiwgJzEnID0gIkhpZ2ggSUMiKQoKcGxvPSBnZ3Bsb3QoZGF0YT1kYXRhSW5wdXQsIGFlcyh5PWFjY3VyYWN5LCB4PWFzLmZhY3RvcihwaGFzZVQpLGxhYmVsID0gcm91bmQoYWNjdXJhY3ksZGlnaXRzID0gMikpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49YWNjdXJhY3ktc2UsIHltYXg9YWNjdXJhY3krc2UpLCB3aWR0aD0uMSkrCiAgI2dlb21fc2lnbmlmKGNvbXBhcmlzb25zID0gbGlzdChjKCJMb3cgSUMiLCJIaWdoIElDIikpLCBhbm5vdGF0aW9ucz0iKioqIiwgeV9wb3NpdGlvbiA9IDAuOTUsIHRpcF9sZW5ndGggPSAwLjAzKSsKICBsYWJzKHRpdGxlPSJBY2N1cmFjeSBJbiBhbmQgT3V0IG9mIHBoYXNlIFRyYW5zaXRpb24iLHg9Ikluc3RhbmNlIGNvbXBsZXhpdHkiLHk9IkFjY3VyYWN5IikrCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDAuNSwxKSkrCiAgZ2VvbV90ZXh0KGhqdXN0PTAuNSx2anVzdCA9IDUsIGNvbG91cj0id2hpdGUiKSsKICB0aGVtZV9saWdodCgpKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCgpvdXRwdXROYW1lID0gJ3NhdF9hY2NfMDJfZycKcGxvdEV4cG9ydChwbG8sb3V0cHV0TmFtZSxmb2xkZXJPdXRfZmlndXJlcykKCmBgYAoKYGBge3J9CiNMb2dpc3RpYyBSZWdyZXNzaW9uIGZvciBJbi9PdXQgUGhhc2UgdHJhbnNpdGlvbgpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9TQVQKCiNsb2dpc3RpYyB3aXRoIHJhbmRvbSBlZmZlY3RzIChpbnRlcmNlcHQpCmxvZ2l0UmFuZG9tSW50ZXJjZXB0ID0gYnJtMihjb3JyZWN0IH4gcGhhc2VUICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5PWJlcm5vdWxsaShsaW5rPSJsb2dpdCIpLCNiaW5vbWlhbChsaW5rPSJsb2dpdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaCA9IDApCgoKdGFibGVOYW1lPSdzYXRfYWNjXzAyX3InCnNhdmVfc3VtbWFyaXNlX21vZGVsKGxvZ2l0UmFuZG9tSW50ZXJjZXB0LCB0YWJsZU5hbWUpCgpgYGAKCiMjIyMgUGxvdCBUQ0MKCmBgYHtyfQpkYXRhSW5wdXQgPSBkYXRhVHJpYWxfU0FUCmRhdGFJbnB1dCA9IGRhdGFJbnB1dCAlPiUgCiAgbXV0YXRlKHJlZ2lvbiA9IGZjdF9yZWxldmVsKHJlZ2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuZGVyY29uc3RyYWluZWQiLCAiUGhhc2UgVHJhbnNpdGlvbiIsICJPdmVyY29uc3RyYWluZWQiKSklPiUgCiAgbXV0YXRlKHNvbD0gYXMuZmFjdG9yKHNvbCkpICU+JSAKICBtdXRhdGUoc29sID0gZmN0X3JlbGV2ZWwoc29sLCIxIiwgIjAiKSkKCmRhdGFJbnB1dDIgPSBkYXRhSW5wdXQgJT4lIAogIGdyb3VwX2J5KGluc3RhbmNlTnVtYmVyLHJlZ2lvbixzb2wpICU+JSAKICBzdW1tYXJpc2UoYWNjdXJhY3k9bWVhbihjb3JyZWN0KSkKCmBgYAoKYGBge3J9CnNpemVfYmlnID0gMjAKc2l6ZV9zbWFsbCA9IDE2CnNpemVfc3MgPSAxMApzaXplX3hzID0gNwoKCnBsbyA9IGdncGxvdChkYXRhSW5wdXQyLGFlcyh4PXJlZ2lvbix5PWFjY3VyYWN5LGZpbGw9c29sKSkrCiAgIyBnZW9tX2JveGppdHRlcihhZXMoZmlsbD1yZWdpb24pLGppdHRlci5jb2xvciA9IE5BLGppdHRlci5zaGFwZSA9IDIxKSsKICBnZW9tX2JveGppdHRlcihqaXR0ZXIuY29sb3IgPSBOQSxqaXR0ZXIuc2hhcGUgPSAyMSwKICAgICAgICAgICAgICAgICBqaXR0ZXIucGFyYW1zID0gbGlzdChoZWlnaHQ9MCxzZWVkPTEwKSwKICAgICAgICAgICAgICAgICBvdXRsaWVyLnNoYXBlPSBOQSkrCiAgICAgICAgICAgICAgICAgIyxvdXRsaWVyLnNoYXBlID0gNCwgb3V0bGllci5zaXplPTAuOSkrCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkrCiAgc2NhbGVfZmlsbF9tYW51YWwobmFtZSAgPSJSZWdpb24iLAogICAgICAgICAgICAgICAgICAgIGJyZWFrcz1jKCIxIiwiMCIpLAogICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCJTYXRpc2ZpYWJsZSIsIlVuc2F0aXNmaWFibGUiKSwKICAgICAgICAgICAgICAgICAgICB2YWx1ZXM9YygiIzkwQkU2RCIsIiNGOTQxNDQiKSkrCiAgeGxhYigiVHlwaWNhbCBDYXNlIENvbXBsZXhpdHkgKFRDQykiKSsKICB5bGFiKCJIdW1hbiBQZXJmb3JtYW5jZSIpKwogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMpKSkrCiAgeWxpbSgwLjIsMSkKCgpwbG8KZ2dzYXZlKHBhc3RlMChmb2xkZXJPdXRfZmlndXJlcywiL1RDQ19TQVRfYWNjLnBkZiIpLHBsbyx3aWR0aCA9IDcsaGVpZ2h0ID02LHVuaXRzPSJpbiIpCiNicmV3ZXIKYGBgCgojIyMgU2F0aXNpZmFiaWxpdHkgYW5kIFRDQwoKYGBge3IgLCBmaWcuYWxpZ249J2NlbnRlcid9CgpkYXRhSW5wdXQ9ZGF0YVRyaWFsX1NBVCAlPiUgZ3JvdXBfYnkocGhhc2VULHNvbCxwSUQpJT4lc3VtbWFyaXNlKGFjY3VyYWN5MT1tZWFuKGNvcnJlY3QpKSU+JXVuZ3JvdXAoKSU+JWdyb3VwX2J5KHNvbCxwaGFzZVQpJT4lc3VtbWFyaXNlKGFjY3VyYWN5PW1lYW4oYWNjdXJhY3kxKSxzZT1zZShhY2N1cmFjeTEpKSU+JXVuZ3JvdXAoKQoKc29sX25hbWVzIDwtIGMoCiAgICAgICAgICAgICAgICAgICAgYDBgID0gIkNvcnJlY3QgYW5zd2VyOiBOTyIsCiAgICAgICAgICAgICAgICAgICAgYDFgID0gIkNvcnJlY3QgYW5zd2VyOiBZRVMiLAogICAgICAgICAgICAgICAgICAgIGAyYCA9ICJJZiB0aGlzIGlzIGhlcmUgaXQgbWVhbnMgZGF0YSBub3QgZmlsdGVyZWQiCiAgICAgICAgICAgICAgICAgICAgKQoKcGxvPWdncGxvdChkYXRhPWRhdGFJbnB1dCwgYWVzKHk9YWNjdXJhY3ksIHg9YXMuZmFjdG9yKGFzLmxvZ2ljYWwocGhhc2VUKSksIGxhYmVsID0gcm91bmQoYWNjdXJhY3ksZGlnaXRzID0gMiksZ3JvdXA9MSkpICsKICBnZW9tX2xpbmUoKSsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPWFjY3VyYWN5LXNlLCB5bWF4PWFjY3VyYWN5K3NlKSwgd2lkdGg9LjEpICsKICBnZW9tX3BvaW50KHNoYXBlPTIxLCBzaXplPTMsIGZpbGw9IndoaXRlIikrCiAgbGFicyh0aXRsZT0iQWNjdXJhY3kgc2VncmVnYXRlZCBieSBzb2x2YWJpbGl0eSIseD0iSW4gUGhhc2UgVHJhbnNpdGlvbj8iLHk9IkFjY3VyYWN5IikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTAsaGp1c3Q9MC41KSkrCiAgZ2VvbV90ZXh0KGhqdXN0PS0wLjUsIGNvbG91cj0iYmxhY2siKSsKICBmYWNldF9ncmlkKC5+c29sLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKHNvbF9uYW1lcykpCgpvdXRwdXROYW1lID0gJ3NhdF9hY2NfMDNfZycKcGxvdEV4cG9ydChwbG8sb3V0cHV0TmFtZSxmb2xkZXJPdXRfZmlndXJlcykKYGBgCgpgYGB7cn0KZGF0YUlucHV0PSBkYXRhVHJpYWxfU0FUCmRhdGFJbnB1dCRwaGFzZVQgPSBhcy5mYWN0b3IoZGF0YUlucHV0JHBoYXNlVCkKZGF0YUlucHV0JHNvbCA9IGFzLmZhY3RvcihkYXRhSW5wdXQkc29sKQojbG9naXN0aWMgd2l0aCByYW5kb20gZWZmZWN0cyAoaW50ZXJjZXB0KQpsb2dpdFJhbmRvbUludGVyY2VwdCA9IGJybTIoY29ycmVjdCB+IHBoYXNlVCArIHNvbCArIHBoYXNlVDpzb2wgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHk9YmVybm91bGxpKGxpbms9ImxvZ2l0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoID0gMCkKCnRhYmxlTmFtZT0nc2F0X2FjY18wM19yJwpzYXZlX3N1bW1hcmlzZV9tb2RlbChsb2dpdFJhbmRvbUludGVyY2VwdCwgdGFibGVOYW1lKQoKYGBgCgpNYXJnaW5hbCBlZmZlY3RzCgpgYGB7cn0KCiNtYXJnaW5hbF9lZmZlY3RzKGxvZ2l0UmFuZG9tSW50ZXJjZXB0LCBhc2s9RkFMU0UpCnBsb3QobWFyZ2luYWxfZWZmZWN0cyhhbGxNb2RlbHNbWydzYXRfYWNjXzAzX3InXV0pLCBwbG90ID0gVFJVRSwgYXNrID0gRkFMU0UpCgpgYGAKCkVmZmVjdCBvZiBUQ0Mgb24gc2F0aXNmaWFibGUgaW5zdGFuY2VzCgpgYGB7cn0KIyBzdDAxCm1vZGVsID0gYWxsTW9kZWxzW1snc2F0X2FjY18wM19yJ11dCgpmaXQgPSBoeXBvdGhlc2lzKG1vZGVsLCJwaGFzZVQxKyBwaGFzZVQxOnNvbDE9MCIsIHNlZWQ9c2VlZF9icm1zKQoKcHJpbnQoZml0KQoKaGRpKGZpdCRzYW1wbGVzLGNpPTAuOTUpCgpgYGAKCiMjIyMgU2F0aXNmaWFiaWxpdHkgYWxvbmUKCmBgYHtyfQpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9TQVQKZGF0YUlucHV0JHNvbCA9IGFzLmZhY3RvcihkYXRhSW5wdXQkc29sKQojbG9naXN0aWMgd2l0aCByYW5kb20gZWZmZWN0cyAoaW50ZXJjZXB0KQpsb2dpdFJhbmRvbUludGVyY2VwdCA9IGJybTIoY29ycmVjdCB+IHNvbCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseT1iZXJub3VsbGkobGluaz0ibG9naXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2ggPSAwKQoKdGFibGVOYW1lPSdzYXRfYWNjXzAzQl9yJwpzYXZlX3N1bW1hcmlzZV9tb2RlbChsb2dpdFJhbmRvbUludGVyY2VwdCwgdGFibGVOYW1lKQoKYGBgCgojIyMgUmVnaW9uIGVmZmVjdCBvbiBBY2N1cmFjeQpPdmVyY29uc3RyYWluZWQgLSBVbmRlcmNvbnN0cmFpbmVkIC0gU2F0aXNmaWFiaWxpdHkgdGhyZXNob2xkCgpgYGB7ciAsIGZpZy5hbGlnbj0nY2VudGVyJ30KZGF0YUlucHV0PWRhdGFUcmlhbF9TQVQKCiMgZGF0YUlucHV0JHBJRD1hcy5jaGFyYWN0ZXIoZGF0YUlucHV0JHBJRCkKIyBwcyA9IHNhbXBsZShwdWxsKGRhdGFJbnB1dCxwSUQpLDIwKQojIGRhdGFJbnB1dCA9IGRhdGFJbnB1dCAlPiUgZmlsdGVyKHBJRCAlaW4lIHBzKQoKCmRhdGFJbnB1dDI9ZGF0YUlucHV0ICU+JSBncm91cF9ieShyZWdpb24scElEKSU+JXN1bW1hcmlzZShhY2N1cmFjeTE9bWVhbihjb3JyZWN0KSklPiUKICB1bmdyb3VwKCklPiVncm91cF9ieShyZWdpb24pJT4lc3VtbWFyaXNlKGFjY3VyYWN5PW1lYW4oYWNjdXJhY3kxKSxzZT1zZShhY2N1cmFjeTEpKSU+JXVuZ3JvdXAoKQoKZGF0YUlucHV0MiRyZWdpb24gPC0gZmFjdG9yKGRhdGFJbnB1dDIkcmVnaW9uLCBsZXZlbHMgPSBjKCdVbmRlcmNvbnN0cmFpbmVkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdQaGFzZSBUcmFuc2l0aW9uJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdPdmVyY29uc3RyYWluZWQnKSkKCnBsbz0gZ2dwbG90KGRhdGE9ZGF0YUlucHV0MiwgYWVzKHk9YWNjdXJhY3ksIHg9cmVnaW9uLCBsYWJlbCA9IHJvdW5kKGFjY3VyYWN5LGRpZ2l0cyA9IDIpKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPWFjY3VyYWN5LXNlLCB5bWF4PWFjY3VyYWN5K3NlKSwgd2lkdGg9LjEpKwogIGxhYnModGl0bGU9IkFjY3VyYWN5IGJ5IHJlZ2lvbiIseD0iUmVnaW9uIix5PSJBY2N1cmFjeSIpKwogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLjUsMSkpKwogIGdlb21fdGV4dChoanVzdD0wLjUsdmp1c3QgPSA1LCBjb2xvdXI9IndoaXRlIikgKwogIHRoZW1lX2xpZ2h0KCkrCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKCm91dHB1dE5hbWUgPSAnc2F0X2FjY18wNF9nJwpwbG90RXhwb3J0KHBsbyxvdXRwdXROYW1lLGZvbGRlck91dF9maWd1cmVzKQoKI1N0YXRzIHRlc3QgZm9yIHRpbWUgaW4gYW5kIG91dCBvZiBwaGFzZSB0cmFuc2l0aW9uOiBBTk9WQQpkYXRhSW5wdXQkb3ZlckNvbnN0cmFpbmVkPSAoZGF0YUlucHV0JHJlZ2lvbj09J092ZXJjb25zdHJhaW5lZCcpCmRhdGFJbnB1dCR1bmRlckNvbnN0cmFpbmVkPSAoZGF0YUlucHV0JHJlZ2lvbj09J1VuZGVyY29uc3RyYWluZWQnKQoKYGBgCgpgYGB7cn0KCmxvZ2l0UmFuZG9tSW50ZXJjZXB0ID0gYnJtMihjb3JyZWN0IH4gb3ZlckNvbnN0cmFpbmVkICsgdW5kZXJDb25zdHJhaW5lZCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseT1iZXJub3VsbGkobGluaz0ibG9naXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwKQoKdGFibGVOYW1lPSdzYXRfYWNjXzA0X3JfQScKc2F2ZV9zdW1tYXJpc2VfbW9kZWwobG9naXRSYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKCmBgYAoKSXMgdGhlcmUgYSBkaWZmZXJlbmNlIGJldHdlZW4gYWNjdXJhY3kgaW4gdGhlIG92ZXJjb25zdHJhaW5lZCByZWdpb24gYW5kCnRoZSB1bmRlcmNvbnN0cmFpbmVkIHJlZ2lvbj8KCmBgYHtyfQoKZml0ID0gaHlwb3RoZXNpcyhhbGxNb2RlbHNbWydzYXRfYWNjXzA0X3JfQSddXSwib3ZlckNvbnN0cmFpbmVkVFJVRT11bmRlckNvbnN0cmFpbmVkVFJVRSIsIHNlZWQ9c2VlZF9icm1zKQoKcHJpbnQoZml0KQoKaGRpKGZpdCRzYW1wbGVzLGNpPTAuOTUpCgpgYGAKCioqUmVnaW9uIEVmZmVjdCBvbiBBY2N1cmFjeSBieSByZWdpb24gYW5kIFNhdGlzZmlhYmlsaXR5KioKCmBgYHtyICwgZmlnLmFsaWduPSdjZW50ZXInfQpkYXRhSW5wdXQ9ZGF0YVRyaWFsX1NBVCAKCiMgZGF0YUlucHV0JHBJRD1hcy5jaGFyYWN0ZXIoZGF0YUlucHV0JHBJRCkKIyBwcyA9IHNhbXBsZShwdWxsKGRhdGFJbnB1dCxwSUQpLDIwKQojIGRhdGFJbnB1dCA9IGRhdGFJbnB1dCAlPiUgZmlsdGVyKHBJRCAlaW4lIHBzKQoKZGF0YUlucHV0Mj1kYXRhSW5wdXQgJT4lIGdyb3VwX2J5KHJlZ2lvbixwSUQsc29sKSU+JXN1bW1hcmlzZShhY2N1cmFjeTE9bWVhbihjb3JyZWN0KSklPiV1bmdyb3VwKCklPiVncm91cF9ieShyZWdpb24sc29sKSU+JXN1bW1hcmlzZShhY2N1cmFjeT1tZWFuKGFjY3VyYWN5MSksc2U9c2UoYWNjdXJhY3kxKSklPiV1bmdyb3VwKCkKCmRhdGFJbnB1dDIkcmVnaW9uIDwtIGZhY3RvcihkYXRhSW5wdXQyJHJlZ2lvbiwgbGV2ZWxzID0gYygnVW5kZXJjb25zdHJhaW5lZCcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnUGhhc2UgVHJhbnNpdGlvbicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnT3ZlcmNvbnN0cmFpbmVkJykpCgpkYXRhSW5wdXQyJHNvbCA9IHJlY29kZShkYXRhSW5wdXQyJHNvbCwgJzEnID0gIlNvbHZhYmxlIiwgJzAnID0gIk5vbi1Tb2x2YWJsZSIpCgpwbG89IGdncGxvdChkYXRhPWRhdGFJbnB1dDIsIGFlcyh5PWFjY3VyYWN5LCB4PXJlZ2lvbiwgbGFiZWwgPSByb3VuZChhY2N1cmFjeSxkaWdpdHMgPSAyKSkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikrCiAgI2dlb21fc2lnbmlmKGFubm90YXRpb25zID0gYygiKioqIiwiKioqIiksCiAgIyAgICAgICAgICAgIHlfcG9zaXRpb249YygwLjk1LDAuOTUpLHhtaW49YygxLjEsMi4xKSx4bWF4PWMoMS45LDIuOSkpKwogICNnZW9tX3NpZ25pZihjb21wYXJpc29ucyA9IGxpc3QoYygiVW5kZXJjb25zdHJhaW5lZCIsIk92ZXJjb25zdHJhaW5lZCIpKSwKICAjICAgICAgICAgICAgIGFubm90YXRpb25zPSJOUyIsIHlfcG9zaXRpb24gPSAwLjk5LCB0aXBfbGVuZ3RoID0gMC4wMykrCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1hY2N1cmFjeS1zZSwgeW1heD1hY2N1cmFjeStzZSksIHdpZHRoPS4xKSsKICBsYWJzKHRpdGxlPSJBY2N1cmFjeSBieSByZWdpb24iLHg9IlJlZ2lvbiIseT0iQWNjdXJhY3kiKSsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbSA9IGMoMC41LDEpKSsKICBnZW9tX3RleHQoaGp1c3Q9MC41LHZqdXN0ID0gNSwgY29sb3VyPSJ3aGl0ZSIpICsKICB0aGVtZV9saWdodCgpKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIAogICAgICAgIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpKwogIGZhY2V0X2dyaWQoLn5zb2wpCgoKb3V0cHV0TmFtZSA9ICdzYXRfYWNjXzA0X2cnCnBsb3RFeHBvcnQocGxvLG91dHB1dE5hbWUsZm9sZGVyT3V0X2ZpZ3VyZXMpCgojU3RhdHMgdGVzdCBmb3IgdGltZSBpbiBhbmQgb3V0IG9mIHBoYXNlIHRyYW5zaXRpb246IEFOT1ZBCmRhdGFJbnB1dCRvdmVyQ29uc3RyYWluZWQ9IChkYXRhSW5wdXQkcmVnaW9uPT0nT3ZlcmNvbnN0cmFpbmVkJykKZGF0YUlucHV0JHVuZGVyQ29uc3RyYWluZWQ9IChkYXRhSW5wdXQkcmVnaW9uPT0nVW5kZXJjb25zdHJhaW5lZCcpCgpgYGAKCiMjIyBOdW1iZXIgb2Ygc29sdXRpb25zIHdpdG5lc3NlcyB0aGF0IHNhdGlzZnkgdGhlIGNvbnN0cmFpbnRzIHsjc2F0X2FjY19uc29sfQoKYGBge3IsIGZpZy5hbGlnbj0nY2VudGVyJ30KZGF0YUlucHV0PWRhdGFUcmlhbF9TQVQKI2RhdGFJbnB1dD1uU29sdXRpb25zX3NhdChkYXRhSW5wdXQpCgojUGxvdHMgblNvbHV0aW9ucyAoeCkgdnMuIEFjY3VyYWN5ICh5KQpkYXRhSW5wdXQzID0gZGF0YUlucHV0ICU+JSBncm91cF9ieShuU29sdXRpb25zLHBJRCxwaGFzZVQpJT4lc3VtbWFyaXNlKGFjY3VyYWN5TWVhbnM9bWVhbihjb3JyZWN0KSklPiV1bmdyb3VwKCklPiVncm91cF9ieShuU29sdXRpb25zLHBoYXNlVCklPiVzdW1tYXJpc2UoYWNjdXJhY3k9bWVhbihhY2N1cmFjeU1lYW5zKSxzZT1zZShhY2N1cmFjeU1lYW5zKSklPiV1bmdyb3VwKCkKCmRhdGFJbnB1dDMkc29sID0gZGF0YUlucHV0MyRuU29sdXRpb25zPj0xCmRhdGFJbnB1dDMkcGhhc2VUID0gcmVjb2RlKGRhdGFJbnB1dDMkcGhhc2VULCAnMCcgPSAiTG93IElDIiwgJzEnID0gIkhpZ2ggSUMiKQoKcGxvPSBnZ3Bsb3QoZGF0YT1kYXRhSW5wdXQzLCBhZXMoeT1hY2N1cmFjeSwgeD1hcy5mYWN0b3IoblNvbHV0aW9ucykpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1hY2N1cmFjeS1zZSwgeW1heD1hY2N1cmFjeStzZSksIHdpZHRoPS4xKSsKICBnZW9tX3BvaW50KHNoYXBlPTIzLCBzaXplPTMsIGZpbGw9InJlZCIpKwogIGxhYnModGl0bGU9IkFjY3VyYWN5IGFuZCB0aGUgTnVtYmVyIG9mIFNvbHV0aW9ucyIsCiAgICAgICB4PSJOdW1iZXIgb2YgICBTb2x1dGlvbnMiLHk9IkFjY3VyYWN5IikrCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDAuNSwxKSkrCiAgdGhlbWVfbGlnaHQoKSsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLHN0cmlwLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSkrCiAgZmFjZXRfZ3JpZChwaGFzZVR+c29sLCBzY2FsZXMgPSAiZnJlZV94Iiwgc3BhY2UgPSAiZnJlZV94IikrCiAgZ2VvbV9zbW9vdGgoZGF0YT1kYXRhSW5wdXQzLCBhZXMoeT1hY2N1cmFjeSwgeD1uU29sdXRpb25zKSxtZXRob2Q9Z2xtLHNlPUZBTFNFLGZ1bGxyYW5nZT1UUlVFLGxpbmV0eXBlID0gImRhc2hlZCIpCgpvdXRwdXROYW1lID0gJ3NhdF9hY2NfMDVfZycKcGxvdEV4cG9ydChwbG8sb3V0cHV0TmFtZSxmb2xkZXJPdXRfZmlndXJlcykKYGBgCgpEaWZmZXJlbmNlIGluIHRoZSBudW1iZXIgb2Ygc29sdXRpb25zIG9mIGluc3RhbmNlcyBIaWdoL0xvdyBUQ0MgKGNsZWFybHksIG9ubHkgZm9yIHNvbHZhYmxlIGluc3RhbmNlcykKCmBgYHtyfQoKZGF0YUlucHV0MiA9IHVuaXF1ZShkYXRhSW5wdXQgJT4lIHNlbGVjdChwaGFzZVQsaWQsblNvbHV0aW9ucyxzb2wpICU+JSBmaWx0ZXIoc29sPT0xKSkKZGlmZk1lYW5zID0gdC50ZXN0KG5Tb2x1dGlvbnMgfiBwaGFzZVQgLGRhdGE9ZGF0YUlucHV0MikKcGFuZGVyKGRpZmZNZWFucykKCmBgYAoKUmVncmVzc2lvbiBmb3IgdGhlIG51bWJlciBvZiB3aXRuZXNzZXMgYW5hbHlzaXM6CmBjb3JyZWN0IH4gc29sICsgcGhhc2VUICsgblNvbHV0aW9ucyArIHBoYXNlVDpuU29sdXRpb25zICsgKDF8cElEKWAKCmBgYHtyfQpkYXRhSW5wdXQgPSBkYXRhSW5wdXQgJT4lIGZpbHRlcihzb2w9PTEpCgojSW5jbHVkZXMgYSBkdW1teSBpZiBuU29sdXRpb25zPT0wLCB0aGF0J3MgdmFyaWFibGU6IHNvbC4KbG9naXRSYW5kb21JbnRlcmNlcHQgPSBicm0yKGNvcnJlY3QgfiBwaGFzZVQgKyBuU29sdXRpb25zICsgcGhhc2VUOm5Tb2x1dGlvbnMgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHk9YmVybm91bGxpKGxpbms9ImxvZ2l0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCkKCnRhYmxlTmFtZT0nc2F0X2FjY18wNV9yX0EnCnNhdmVfc3VtbWFyaXNlX21vZGVsKGxvZ2l0UmFuZG9tSW50ZXJjZXB0LCB0YWJsZU5hbWUpCmBgYAoKVGhpcyBjYWxjdWxhdGVzIHRoZSBzaWduaWZpY2FuY2Ugb2YgdGhlIGJldGEoc2xvcGUpIG9mIHRoZSBudW1iZXJPZlNvbHV0aW9ucyBmb3IgaGlnaCBUQ0MgaW5zdGFuY2VzLgoKYGBge3J9CiNUaGlzIHZlcnNpb24gcmVjb2RlcyBwaGFzZVQgdG8gT3V0cGhhc2VULCB0byAKCmZpdCA9IGh5cG90aGVzaXMoYWxsTW9kZWxzW1snc2F0X2FjY18wNV9yX0EnXV0sIm5Tb2x1dGlvbnMgKyBwaGFzZVQ6blNvbHV0aW9ucyA9IDAiLCBzZWVkPXNlZWRfYnJtcykKCnByaW50KGZpdCkKCmhkaShmaXQkc2FtcGxlcyxjaT0wLjk1KQpgYGAKCk1hcmdpbmFsIEVmZmVjdHMKCmBgYHtyfQoKcGxvdChtYXJnaW5hbF9lZmZlY3RzKGFsbE1vZGVsc1tbJ3NhdF9hY2NfMDVfcl9BJ11dKSwgcGxvdCA9IFRSVUUsIGFzayA9IEZBTFNFKQoKYGBgCgojIyMjIE5Tb2wgKHJlZ3Jlc3NlZCBhbG9uZSkKCmBgYHtyfQojc3QwMgpkYXRhSW5wdXQgPSBkYXRhVHJpYWxfU0FUCmRhdGFJbnB1dCA9IGRhdGFJbnB1dCAlPiUgZmlsdGVyKHNvbD09MSkKCiNJbmNsdWRlcyBhIGR1bW15IGlmIG5Tb2x1dGlvbnM9PTAsIHRoYXQncyB2YXJpYWJsZTogc29sLgpsb2dpdFJhbmRvbUludGVyY2VwdCA9IGJybTIoY29ycmVjdCB+IG5Tb2x1dGlvbnMgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHk9YmVybm91bGxpKGxpbms9ImxvZ2l0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCkKCnRhYmxlTmFtZT0nc2F0X2FjY18wNV9yX0InCnNhdmVfc3VtbWFyaXNlX21vZGVsKGxvZ2l0UmFuZG9tSW50ZXJjZXB0LCB0YWJsZU5hbWUpCmBgYAoKYGBge3J9Cm1lYW5fYWNjID0gZGF0YUlucHV0ICU+JSBncm91cF9ieShpbnN0YW5jZU51bWJlcixuU29sdXRpb25zLCBzb2wscGhhc2VUKSAlPiUKICBzdW1tYXJpc2UoYWNjdXJhY3k9bWVhbihjb3JyZWN0KSkgCgpsb2dpdFJhbmRvbUludGVyY2VwdCA9IGFsbE1vZGVsc1tbJ3NhdF9hY2NfMDVfcl9CJ11dCnBwICA9IHBsb3QoY29uZGl0aW9uYWxfZWZmZWN0cyhsb2dpdFJhbmRvbUludGVyY2VwdCksIHBsb3QgPSBGQUxTRSwgYXNrID0gRkFMU0UpCgpwcCRuU29sdXRpb25zICsgCiAgZ2VvbV9wb2ludChkYXRhPW1lYW5fYWNjLGFlcyh4ID0gblNvbHV0aW9ucywgeSA9IGFjY3VyYWN5KSxpbmhlcml0LmFlcyA9IEZBTFNFKQpgYGAKCmBgYHtyfQojIEltcHJvdmluZyB0aGUgcGxvdApzaXplX2JpZyA9IDIwCnNpemVfc21hbGwgPSAxNgpzaXplX3NzID0gMTAKc2l6ZV94cyA9IDcKCnBwX3Bsb3QgPSBwcCRuU29sdXRpb25zCnBwX3Bsb3QkbGF5ZXJzW1sxXV0kZ2VvbV9wYXJhbXMkc2UgPSBGQUxTRQpwcF9wbG90JGxheWVyc1tbMV1dJGFlc19wYXJhbXMkY29sb3VyPSIjNTc3NTkwIgoKcHBfcGxvdCRsYXllcnMgPC0gYyhnZW9tX3BvaW50KGRhdGE9bWVhbl9hY2MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IG5Tb2x1dGlvbnMsIHkgPSBhY2N1cmFjeSwgY29sPWFzLmZhY3Rvcihzb2wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpLCBzaXplPTIuNSksIGluaGVyaXQuYWVzID0gRkFMU0UpLAogICAgICAgICAgICAgICAgICAgICAgICAgcHBfcGxvdCRsYXllcnMpCgoKcGxvID0gcHBfcGxvdCArCiAgeGxhYigiTnVtYmVyIG9mIHNvbHV0aW9uIFdpdG5lc3NlcyIpKyNleHByZXNzaW9uKElDW2V4cG9zdF0pKSsKICB5bGFiKCJIdW1hbiBQZXJmb3JtYW5jZSIpKwogIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lPSIiLHZhbHVlcyA9IGMoMTcsMTYpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWU9IiIsdmFsdWVzID0gYygiMSI9IiM5MEJFNkQiLCIwIj0iI0Y5NDE0NCIpKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMSwzLDUsNyw5KSxsaW1pdHMgPWMoMSwxMCkpKwogIGd1aWRlcyhzaGFwZSA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzKSkpKwogIHlsaW0oMC4yLDEpCgoKcGxvCmdnc2F2ZShwYXN0ZTAoZm9sZGVyT3V0X2ZpZ3VyZXMsIi9Od2l0X1NBVF9hY2MucGRmIikscGxvLHdpZHRoID0gNixoZWlnaHQgPTYsdW5pdHM9ImluIikKYGBgCgojIyMjIE5Tb2wgKHdpdGggVENDIGFuZCBubyBpbnRlcmFjdGlvbikKCmBgYHtyfQojc3QwMwpkYXRhSW5wdXQgPSBkYXRhVHJpYWxfU0FUCmRhdGFJbnB1dCA9IGRhdGFJbnB1dCAlPiUgZmlsdGVyKHNvbD09MSkKCmxvZ2l0UmFuZG9tSW50ZXJjZXB0ID0gYnJtMihjb3JyZWN0IH4gblNvbHV0aW9ucyArIHBoYXNlVCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseT1iZXJub3VsbGkobGluaz0ibG9naXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwKQoKdGFibGVOYW1lPSdzYXRfYWNjXzA1X3JfQycKc2F2ZV9zdW1tYXJpc2VfbW9kZWwobG9naXRSYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKYGBgCgojIyMgSUNfZXhwb3N0IHsjc2F0X2FjY19JQ2V4cG9zdH0KCmBgYHtyLCBmaWcuYWxpZ249J2NlbnRlcid9CmRhdGFJbnB1dCA9IGRhdGFUcmlhbF9TQVQKCiMgU3VtbWFyaXNlIHRoZSBkYXRhIHRvIHBsb3QKbWVhbl9hY2N1cmFjeSA9IGRhdGFJbnB1dCAlPiUgCiAgZ3JvdXBfYnkoaW5zdGFuY2VOdW1iZXIsIHNvbCwgSUNleHBvc3QsIHBoYXNlVCwgblNvbHV0aW9ucykgJT4lIAogIHN1bW1hcmlzZShhY2N1cmFjeSA9IG1lYW4oY29ycmVjdCkpCgpnZ3Bsb3QobWVhbl9hY2N1cmFjeSwgYWVzKHggPSBJQ2V4cG9zdCwgeSA9IGFjY3VyYWN5KSkrCiAgZ2VvbV9wb2ludCgpICsKICB0aGVtZV9saWdodCgpICsKICBzdGF0X3Ntb290aChmb3JtdWxhID0gIHkgfiBJKHheMC4wMSksIG1ldGhvZD0ibG0iLCBzZT0gRkFMU0UpKwogIHhsYWIoIklDX2V4cG9zdCIpKwogIHlsYWIoIkh1bWFuIEFjY3VyYWN5IikKCmBgYAoKYGBge3J9CmRhdGFJbnB1dCA9IGRhdGFUcmlhbF9TQVQKbW9kZWxfSUNleHBvc3QgPSBicm0yKGNvcnJlY3QgfiBJQ2V4cG9zdCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseT1iZXJub3VsbGkobGluaz0ibG9naXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaCA9IDApCgp0YWJsZU5hbWU9J3NhdF9hY2NfaWNleHBvc3RfYWxsJwpzYXZlX3N1bW1hcmlzZV9tb2RlbChtb2RlbF9JQ2V4cG9zdCwgdGFibGVOYW1lKQpgYGAKCmBgYHtyfQptZWFuX2FjY3VyYWN5JGNvcnJlY3Q9IG1lYW5fYWNjdXJhY3kkYWNjdXJhY3kKCm1vZGVsX0lDZXhwb3N0ID0gYWxsTW9kZWxzW1snc2F0X2FjY19pY2V4cG9zdF9hbGwnXV0KcHAgID0gcGxvdChjb25kaXRpb25hbF9lZmZlY3RzKG1vZGVsX0lDZXhwb3N0KSwgcGxvdCA9IEZBTFNFLCBhc2sgPSBGQUxTRSkKCnBwJElDZXhwb3N0ICsgCiAgZ2VvbV9wb2ludChkYXRhPW1lYW5fYWNjdXJhY3ksYWVzKHggPSBJQ2V4cG9zdCwgeSA9IGNvcnJlY3QpLGluaGVyaXQuYWVzID0gRkFMU0UpCmBgYAoKYGBge3J9CiMgSW1wcm92aW5nIHRoZSBwbG90CnNpemVfYmlnID0gMjAKc2l6ZV9zbWFsbCA9IDE2CnNpemVfc3MgPSAxMApzaXplX3hzID0gNwoKcHBfcGxvdCA9IHBwJElDZXhwb3N0CnBwX3Bsb3QkbGF5ZXJzW1sxXV0kZ2VvbV9wYXJhbXMkc2UgPSBGQUxTRQpwcF9wbG90JGxheWVyc1tbMV1dJGFlc19wYXJhbXMkY29sb3VyPSIjNTc3NTkwIgoKcHBfcGxvdCRsYXllcnMgPC0gYyhnZW9tX3BvaW50KGRhdGE9bWVhbl9hY2N1cmFjeSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gSUNleHBvc3QsIHkgPSBjb3JyZWN0LCBjb2w9YXMuZmFjdG9yKHNvbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcGU9YXMuZmFjdG9yKHBoYXNlVCksIHNpemU9Mi41KSwgaW5oZXJpdC5hZXMgPSBGQUxTRSksCiAgICAgICAgICAgICAgICAgICAgICAgICBwcF9wbG90JGxheWVycykKCgpwbG8gPSBwcF9wbG90ICsKICB4bGFiKCJJbnN0YW5jZSBDb21wbGV4aXR5IChJQykiKSsjZXhwcmVzc2lvbihJQ1tleHBvc3RdKSkrCiAgeWxhYigiSHVtYW4gUGVyZm9ybWFuY2UiKSsKICBzY2FsZV9zaGFwZV9tYW51YWwobmFtZT0iIix2YWx1ZXMgPSBjKDE3LDE2KSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbChuYW1lPSIiLHZhbHVlcyA9IGMoIjEiPSIjOTBCRTZEIiwiMCI9IiNGOTQxNDQiKSkrCiAgdGhlbWVfY2xhc3NpYygpKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0gc2l6ZV9iaWcpLAogICAgICAgYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPXNpemVfc21hbGwpLAogICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSsKICBndWlkZXMoc2hhcGUgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gMykpKSsKICB5bGltKDAuMiwxKQoKcGxvCmdnc2F2ZShwYXN0ZTAoZm9sZGVyT3V0X2ZpZ3VyZXMsIi9JQ19TQVRfYWNjLnBkZiIpLHBsbyx3aWR0aCA9IDYsaGVpZ2h0ID02LHVuaXRzPSJpbiIpCmBgYAoKYGBge3J9CiMgSW1wcm92aW5nIHRoZSBwbG90CnNpemVfYmlnID0gMjAKc2l6ZV9zbWFsbCA9IDE2CnNpemVfc3MgPSAxMApzaXplX3hzID0gNwoKcGxvID0gcHAkSUNleHBvc3QgKwpnZW9tX3BvaW50KGRhdGE9bWVhbl9hY2N1cmFjeSxhZXMoeCA9IElDZXhwb3N0LCB5ID0gY29ycmVjdCwgY29sPWFzLmZhY3RvcihwaGFzZVQpLHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpLCBzaXplPTIuNSksaW5oZXJpdC5hZXMgPSBGQUxTRSkrCiAgeGxhYigiSW5zdGFuY2UgQ29tcGxleGl0eSAoSUMpIikrI2V4cHJlc3Npb24oSUNbZXhwb3N0XSkpKwogIHlsYWIoIkh1bWFuIFBlcmZvcm1hbmNlIikrCiAgc2NhbGVfc2hhcGVfbWFudWFsKG5hbWU9IiIsdmFsdWVzID0gYygxNywxNikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwobmFtZT0iIix2YWx1ZXMgPSBjKCAiI0ZDNEUwNyIsIiNFN0I4MDAiKSkrCiAgdGhlbWVfY2xhc3NpYygpKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0gc2l6ZV9iaWcpLAogICAgICAgYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPXNpemVfc21hbGwpLAogICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSsKICBndWlkZXMoc2hhcGUgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gMykpKQoKcGxvCmdnc2F2ZShwYXN0ZTAoZm9sZGVyT3V0X2ZpZ3VyZXMsIi9JQ19TQVRfYWNjLnBkZiIpLHBsbyx3aWR0aCA9IDYsaGVpZ2h0ID02LHVuaXRzPSJpbiIpCmBgYAoKTW9kZWwgRml0CgpgYGB7cn0KbW9kZWxfSUNleHBvc3QgPSBhbGxNb2RlbHNbWydzYXRfYWNjX2ljZXhwb3N0X2FsbCddXQpkYXRhSW5wdXQgPSBkYXRhVHJpYWxfU0FUCgojIE1ha2UgcHJlZGljdGlvbnMgZXhjbHVkaW5nIHJhbmRvbSBlZmZlY3RzIChwSUQpCnByZWRpY3Rpb25zID0gcHJlZGljdChtb2RlbF9JQ2V4cG9zdCxkYXRhSW5wdXQsIHJlX2Zvcm11bGEgPSBOQSkKCgojIEVzdGltYXRpbmcgdGhlIHNpZ25pZmljYW5jZSBvZiB0aGUgZml0LiBUaGlzIGlzIGRvbmUgY29uc2lkZXJpbmcgdGhlIHByb2JhYmlsaXR5IGVzdGltYXRpb24gcmF0aGVyIHRoYW4gdGhlIGJpbmFyeSBjbGFzc2lmaWNhdGlvbi4KCiNQZXJmb3JtcyB0aGUgSG9zbWVyLUxlbWVzaG93IGdvb2RuZXNzIG9mIGZpdCB0ZXN0CmxvZ2lzdGljX3NpZ25pZmljYW5jZSA9IGdlbmVyYWxob3NsZW06OmxvZ2l0Z29mKGRhdGFJbnB1dCRjb3JyZWN0LCBwcmVkaWN0aW9uc1ssMV0sIGcgPSAxMCwgb3JkID0gRkFMU0UpCmxvZ2lzdGljX3NpZ25pZmljYW5jZQoKIyBGaW5kcyBSMiB1c2luZyBiaW5hcnkgb3V0Y29tZXMKIyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy80MDkwMTQ0NS9mdW5jdGlvbi10by1jYWxjdWxhdGUtcjItci1zcXVhcmVkLWluLXIKI3ByZWRpY3Rpb25zID0gcHJlZGljdChtb2RlbF9JQ2V4cG9zdCxkYXRhSW5wdXQsIHJlX2Zvcm11bGEgPSBOQSkKI3JfMl9iaW5hcnkgPSBjb3IoZGF0YUlucHV0JElDZXhwb3N0LCBwcmVkaWN0aW9uc1ssMV0pXjIKcl8yX2JpbmFyeSA9IGNvcihkYXRhSW5wdXQkY29ycmVjdCwgcHJlZGljdGlvbnNbLDFdKV4yCnJfMl9iaW5hcnkKCiMgRmluZHMgUjIgdXNpbmcgbWVhbiBhY2N1cmFjaWVzIHBlciBpbnN0YW5jZQpwcmVkaWN0aW9uczIgPSBwcmVkaWN0KG1vZGVsX0lDZXhwb3N0LG1lYW5fYWNjdXJhY3ksIHJlX2Zvcm11bGEgPSBOQSkKcl8yX3Byb2JhYmlsaXRpZXMgPSBjb3IobWVhbl9hY2N1cmFjeSRhY2N1cmFjeSwgcHJlZGljdGlvbnMyWywxXSleMgpyXzJfcHJvYmFiaWxpdGllcwpgYGAKCiMjIyMgT25seSB1bnNhdGlzZmlhYmxlIGluc3RhbmNlcwoKYGBge3J9CmRhdGFJbnB1dCA9IGRhdGFUcmlhbF9TQVQKZGF0YUlucHV0ID0gZGF0YUlucHV0ICU+JSBmaWx0ZXIoc29sPT0wKQptb2RlbF9JQ2V4cG9zdCA9IGJybTIoY29ycmVjdCB+IElDZXhwb3N0ICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5PWJlcm5vdWxsaShsaW5rPSJsb2dpdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoID0gMCkKCnRhYmxlTmFtZT0nc2F0X2FjY19pY2V4cG9zdCcKc2F2ZV9zdW1tYXJpc2VfbW9kZWwobW9kZWxfSUNleHBvc3QsIHRhYmxlTmFtZSkKYGBgCgpgYGB7cn0KbWVhbl9hY2N1cmFjeTIgPSBkYXRhSW5wdXQgJT4lIAogIGZpbHRlcihzb2wgPT0gMCkgJT4lIAogIGdyb3VwX2J5KGluc3RhbmNlTnVtYmVyLCBzb2wsIElDZXhwb3N0LCBwaGFzZVQsIG5Tb2x1dGlvbnMpICU+JSAKICBzdW1tYXJpc2UoYWNjdXJhY3kgPSBtZWFuKGNvcnJlY3QpKQoKbWVhbl9hY2N1cmFjeTIkY29ycmVjdD0gbWVhbl9hY2N1cmFjeTIkYWNjdXJhY3kKCm1vZGVsX0lDZXhwb3N0ID0gYWxsTW9kZWxzW1snc2F0X2FjY19pY2V4cG9zdCddXQpwcCAgPSBwbG90KGNvbmRpdGlvbmFsX2VmZmVjdHMobW9kZWxfSUNleHBvc3QpLCBwbG90ID0gRkFMU0UsIGFzayA9IEZBTFNFKQoKcHAkSUNleHBvc3QgKyAKICBnZW9tX3BvaW50KGRhdGE9bWVhbl9hY2N1cmFjeTIsYWVzKHggPSBJQ2V4cG9zdCwgeSA9IGNvcnJlY3QpLGluaGVyaXQuYWVzID0gRkFMU0UpCmBgYAoKTW9kZWwgRml0CgpgYGB7cn0KbW9kZWxfSUNleHBvc3QgPSBhbGxNb2RlbHNbWydzYXRfYWNjX2ljZXhwb3N0J11dCiNzdDA1CmRhdGFJbnB1dCA9IGRhdGFUcmlhbF9TQVQgJT4lIGZpbHRlcihzb2w9PTApCgojIE1ha2UgcHJlZGljdGlvbnMgZXhjbHVkaW5nIHJhbmRvbSBlZmZlY3RzIChwSUQpCnByZWRpY3Rpb25zID0gcHJlZGljdChtb2RlbF9JQ2V4cG9zdCxkYXRhSW5wdXQsIHJlX2Zvcm11bGEgPSBOQSkKCgojIEVzdGltYXRpbmcgdGhlIHNpZ25pZmljYW5jZSBvZiB0aGUgZml0LiBUaGlzIGlzIGRvbmUgY29uc2lkZXJpbmcgdGhlIHByb2JhYmlsaXR5IGVzdGltYXRpb24gcmF0aGVyIHRoYW4gdGhlIGJpbmFyeSBjbGFzc2lmaWNhdGlvbi4KCiNQZXJmb3JtcyB0aGUgSG9zbWVyLUxlbWVzaG93IGdvb2RuZXNzIG9mIGZpdCB0ZXN0CmxvZ2lzdGljX3NpZ25pZmljYW5jZSA9IGdlbmVyYWxob3NsZW06OmxvZ2l0Z29mKGRhdGFJbnB1dCRjb3JyZWN0LCBwcmVkaWN0aW9uc1ssMV0sIGcgPSAxMCwgb3JkID0gRkFMU0UpCmxvZ2lzdGljX3NpZ25pZmljYW5jZQoKIyBGaW5kcyBSMiB1c2luZyBiaW5hcnkgb3V0Y29tZXMKIyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy80MDkwMTQ0NS9mdW5jdGlvbi10by1jYWxjdWxhdGUtcjItci1zcXVhcmVkLWluLXIKI3ByZWRpY3Rpb25zID0gcHJlZGljdChtb2RlbF9JQ2V4cG9zdCxkYXRhSW5wdXQsIHJlX2Zvcm11bGEgPSBOQSkKcl8yX2JpbmFyeSA9IGNvcihkYXRhSW5wdXQkY29ycmVjdCwgcHJlZGljdGlvbnNbLDFdKV4yCnJfMl9iaW5hcnkKCiMgRmluZHMgUjIgdXNpbmcgbWVhbiBhY2N1cmFjaWVzIHBlciBpbnN0YW5jZQpwcmVkaWN0aW9uczIgPSBwcmVkaWN0KG1vZGVsX0lDZXhwb3N0LG1lYW5fYWNjdXJhY3kyLCByZV9mb3JtdWxhID0gTkEpCnJfMl9wcm9iYWJpbGl0aWVzID0gY29yKG1lYW5fYWNjdXJhY3kyJGFjY3VyYWN5LCBwcmVkaWN0aW9uczJbLDFdKV4yCnJfMl9wcm9iYWJpbGl0aWVzCmBgYAoKIyMgVGltZSBTcGVudAoKVGhlIGRlZmF1bHQgZGF0YSB1c2VkIGluIHRoaXMgc2VjdGlvbiBpcyBgZGF0YVRyaWFsX1NBVF9UaW1lYC4gVGhpcyBkYXRhc2V0IGV4Y2x1ZGVzIHRob3NlIHBhcnRpY2lwYW50cyB0aGF0IG5ldmVyIHNraXBwZWQgdG8gYW5zd2VyIHN1Ym1pc3Npb24uCgpXZSBmaXJzdCBjYWxjdWxhdGUgc29tZSBzdW1tYXJ5IHN0YXRzIGZvciB0aGUgd2hvbGUgZGF0YSBzZXQgKGBkYXRhVHJpYWxfU0FUYCkgYW5kIHNlZSBob3cgbWFueSBwYXJ0aWNpcGFudHMgd2VyZSBleGNsdWRlZCBpbiBgZGF0YVRyaWFsX1NBVF9UaW1lYC4KCiMjIyMgU3VtbVN0YXRzIGBTQVRgCgpgYGB7ciwgcmVzdWx0cz0nYXNpcyd9CiNTdW1tYXJ5IFN0YXRzIGZvciBEZWNpc2lvbiBQcm9ibGVtCmRhdGFJbnB1dD1kYXRhVHJpYWxfU0FUCgp0aW1lU3VtbWFyeSA9IGRhdGFJbnB1dCAlPiUgZ3JvdXBfYnkocElEKSAlPiUgc3VtbWFyaXNlKGFjYz1tZWFuKHRpbWVTcGVudCkpICU+JSBzdW1tYXJpc2UobWVhbj1tZWFuKGFjYyksbWluPW1pbihhY2MpLG1heD1tYXgoYWNjKSxTRD1zZChhY2MpKQprYWJsZSh0aW1lU3VtbWFyeSwgZGlnaXRzPTEsIGNhcHRpb24gPSAiVGltZSBTdW1tYXJ5IikKCnllc05vUHJvcG9ydGlvbnMgPSBkYXRhSW5wdXQgJT4lIGdyb3VwX2J5KHNvbCxwSUQpICU+JSBzdW1tYXJpc2UoYWNjPW1lYW4odGltZVNwZW50KSkgJT4lIHN1bW1hcmlzZShtZWFuPW1lYW4oYWNjKSxtaW49bWluKGFjYyksbWF4PW1heChhY2MpLFNEPXNkKGFjYykpCmthYmxlKHllc05vUHJvcG9ydGlvbnMsIGRpZ2l0cz0xLCBjYXB0aW9uID0gIlRpbWUgU3BlbnQgQnkgU29sdXRpb24iKQoKaGlzdChkYXRhSW5wdXQkdGltZVNwZW50LGJyZWFrcz00MCkKCmBgYAoKYGBge3J9CmFsbF9wSURzID0gdW5pcXVlKGRhdGFUcmlhbF9TQVQkcElEKQpwSURzX25vdF9pbl9UaW1lID0gYWxsX3BJRHNbIShhbGxfcElEcyAlaW4lIHVuaXF1ZShkYXRhVHJpYWxfU0FUX1RpbWUkcElEKSldCnByaW50KHBhc3RlMCgiVGhlIHBhcnRpY2lwYW50cyByZW1vdmVkIGluIHRoZSBUSU1FIGRmIGFyZSAiLCBsZW5ndGgocElEc19ub3RfaW5fVGltZSkpKQoKCm9ic19yZW1vdmVkID0gbnJvdyhkYXRhVHJpYWxfU0FUKS1ucm93KGRhdGFUcmlhbF9TQVRfVGltZSkKcHJpbnQocGFzdGUwKCJUaGUgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyByZW1vdmVkIGluIHRoZSBUSU1FIGRmIGlzICIsIG9ic19yZW1vdmVkKSkKCmBgYAoKIyMjIyBTdW1tU3RhdHMgYFNBVF9UaW1lYAoKYGBge3IsIHJlc3VsdHM9J2FzaXMnfQojU3VtbWFyeSBTdGF0cyBmb3IgRGVjaXNpb24gUHJvYmxlbQpkYXRhSW5wdXQ9ZGF0YVRyaWFsX1NBVF9UaW1lCgp0aW1lU3VtbWFyeSA9IGRhdGFJbnB1dCAlPiUgZ3JvdXBfYnkocElEKSAlPiUgc3VtbWFyaXNlKGFjYz1tZWFuKHRpbWVTcGVudCkpICU+JSBzdW1tYXJpc2UobWVhbj1tZWFuKGFjYyksbWluPW1pbihhY2MpLG1heD1tYXgoYWNjKSxTRD1zZChhY2MpKQprYWJsZSh0aW1lU3VtbWFyeSwgZGlnaXRzPTEsIGNhcHRpb24gPSAiVGltZSBTdW1tYXJ5IikKCnllc05vUHJvcG9ydGlvbnMgPSBkYXRhSW5wdXQgJT4lIGdyb3VwX2J5KHNvbCxwSUQpICU+JSBzdW1tYXJpc2UoYWNjPW1lYW4odGltZVNwZW50KSkgJT4lIHN1bW1hcmlzZShtZWFuPW1lYW4oYWNjKSxtaW49bWluKGFjYyksbWF4PW1heChhY2MpLFNEPXNkKGFjYykpCmthYmxlKHllc05vUHJvcG9ydGlvbnMsIGRpZ2l0cz0xLCBjYXB0aW9uID0gIlRpbWUgU3BlbnQgQnkgU29sdXRpb24iKQoKaGlzdChkYXRhSW5wdXQkdGltZVNwZW50LGJyZWFrcz00MCkKCmBgYAoKIyMjIyBFZmZlY3Qgb2YgVHJpYWwgTnVtYmVyIG9uIFRpbWUtb24tdGFzawoKYGBge3J9CiNUcmlhbCAoZXhwZXJpZW5jZSBlZmZlY3QpIGVmZmVjdCBvbiB0aW1lU3BlbnQKZGF0YUlucHV0PWRhdGFUcmlhbF9TQVRfVGltZQpkYXRhSW5wdXQkdG90YWxUcmlhbCA9IGRhdGFJbnB1dCRibG9jayAqIGRhdGFJbnB1dCR0cmlhbAoKc3VtbWFyeUJ5QmxvY2sgPSBkYXRhSW5wdXQgJT4lIGdyb3VwX2J5KGJsb2NrLHBJRCkgJT4lIHN1bW1hcmlzZSh0aW1lPW1lYW4odGltZVNwZW50KSkgJT4lIHN1bW1hcmlzZShtZWFuPW1lYW4odGltZSksbWluPW1pbih0aW1lKSxtYXg9bWF4KHRpbWUpLFNEPXNkKHRpbWUpKQprYWJsZShzdW1tYXJ5QnlCbG9jayxkaWdpdHM9MiAsIGNhcHRpb249IlRpbWUgU3BlbnQgcGVyIFRyaWFsIHNlZ3JlZ2F0ZWQgQnkgQmxvY2siKQoKI1JlZ3Jlc3Npb24KbGluZWFyUmFuZG9tSW50ZXJjZXB0ID0gYnJtMih0aW1lU3BlbnRfcGN0IHwgY2VucyhjZW5zb3JlZF90aW1lKSB+IHRvdGFsVHJpYWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCwgaXRlciA9IGl0ZXJzX2hpZ2gsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBsaXN0KGFkYXB0X2RlbHRhID0gMC45OCkpCgp0YWJsZU5hbWU9J3NhdF90aW1lXzAxX3InCnNhdmVfc3VtbWFyaXNlX21vZGVsKGxpbmVhclJhbmRvbUludGVyY2VwdCwgdGFibGVOYW1lKQoKYGBgCgojIyMgVENDCgpgYGB7ciAsIGZpZy5hbGlnbj0nY2VudGVyJ30KZGF0YUlucHV0PWRhdGFUcmlhbF9TQVRfVGltZSAlPiUgZ3JvdXBfYnkocGhhc2VULHBJRCklPiVzdW1tYXJpc2UodGltZVNwZW50MT1tZWFuKHRpbWVTcGVudCkpJT4ldW5ncm91cCgpJT4lZ3JvdXBfYnkocGhhc2VUKSU+JXN1bW1hcmlzZSh0aW1lU3BlbnQ9bWVhbih0aW1lU3BlbnQxKSxzZT1zZSh0aW1lU3BlbnQxKSklPiV1bmdyb3VwKCkKCmRhdGFJbnB1dCRwaGFzZVQgPSByZWNvZGUoZGF0YUlucHV0JHBoYXNlVCwgJzAnID0gIkxvdyBJQyIsICcxJyA9ICJIaWdoIElDIikKCnBsbz0gZ2dwbG90KGRhdGE9ZGF0YUlucHV0LCBhZXMoeT10aW1lU3BlbnQsIHg9YXMuZmFjdG9yKHBoYXNlVCksbGFiZWwgPSByb3VuZCh0aW1lU3BlbnQsZGlnaXRzID0gMSkpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49dGltZVNwZW50LXNlLCB5bWF4PXRpbWVTcGVudCtzZSksIHdpZHRoPS4xKSsKICAjZ2VvbV9zaWduaWYoY29tcGFyaXNvbnMgPSBsaXN0KGMoIkxvdyBJQyIsIkhpZ2ggSUMiKSksIGFubm90YXRpb25zPSIqKioiLCB5X3Bvc2l0aW9uID0gMC45NSwgdGlwX2xlbmd0aCA9IDAuMDMpKwogIGxhYnModGl0bGU9IlRpbWUgU3BlbnQgSW4gYW5kIE91dCBvZiBwaGFzZSBUcmFuc2l0aW9uIix4PSJJbnN0YW5jZSBjb21wbGV4aXR5Iix5PSJUaW1lIFNwZW50IikrCiAgI2Nvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLjUsMSkpKwogIGdlb21fdGV4dChoanVzdD0wLjUsdmp1c3QgPSA1LCBjb2xvdXI9IndoaXRlIikrCiAgdGhlbWVfbGlnaHQoKSsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQoKb3V0cHV0TmFtZSA9ICJzYXRfdGltZV8wMl9nIgpwbG90RXhwb3J0KHBsbyxvdXRwdXROYW1lLGZvbGRlck91dF9maWd1cmVzKQoKYGBgCgpgYGB7cn0KI0xvZ2lzdGljIFJlZ3Jlc3Npb24gZm9yIEluL091dCBQaGFzZSB0cmFuc2l0aW9uCmRhdGFJbnB1dD0gZGF0YVRyaWFsX1NBVF9UaW1lCgojbG9naXN0aWMgd2l0aCByYW5kb20gZWZmZWN0cyAoaW50ZXJjZXB0KQojIFRUVE9ETwpyYW5kb21JbnRlcmNlcHQgPSBicm0yKHRpbWVTcGVudHwgY2VucyhjZW5zb3JlZF90aW1lKSB+IHBoYXNlVCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwgCiAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywgcmVmcmVzaCA9IDAsIGl0ZXIgPSBpdGVyc19oaWdoKQoKdGFibGVOYW1lPSJzYXRfdGltZV8wMl9yIgpzYXZlX3N1bW1hcmlzZV9tb2RlbChyYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKCmBgYAoKIyMjIyMgUGxvdCBUQ0MKCmBgYHtyfQoKZGF0YUlucHV0ID0gZGF0YVRyaWFsX1NBVF9UaW1lICU+JQogIG11dGF0ZShyZWdpb24gPSBmY3RfcmVsZXZlbChyZWdpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJVbmRlcmNvbnN0cmFpbmVkIiwgIlBoYXNlIFRyYW5zaXRpb24iLCAiT3ZlcmNvbnN0cmFpbmVkIikpICU+JSAKICBtdXRhdGUoc29sPSBhcy5mYWN0b3Ioc29sKSkgJT4lIAogIG11dGF0ZShzb2wgPSBmY3RfcmVsZXZlbChzb2wsIjEiLCAiMCIpKQoKZGF0YUlucHV0JHRpbWVTcGVudF9wY3QgPSBkYXRhSW5wdXQkdGltZVNwZW50L1NBVFRhc2tNYXhUaW1lCmRhdGFJbnB1dDIgPSBkYXRhSW5wdXQgJT4lIAogIGdyb3VwX2J5KGluc3RhbmNlTnVtYmVyLHJlZ2lvbixzb2wsIHBoYXNlVCkgJT4lIAogIHN1bW1hcmlzZSh0aW1lU3BlbnRfcGN0PW1lZGlhbih0aW1lU3BlbnRfcGN0KSkKCmBgYAoKYGBge3J9CnNpemVfYmlnID0gMjAKc2l6ZV9zbWFsbCA9IDE2CnNpemVfc3MgPSAxMApzaXplX3hzID0gNwoKcGxvID0gZ2dwbG90KGRhdGFJbnB1dDIsYWVzKHg9cmVnaW9uLHk9dGltZVNwZW50X3BjdCxmaWxsPXNvbCkpKwogIGdlb21fYm94aml0dGVyKGppdHRlci5jb2xvciA9IE5BLGppdHRlci5zaGFwZSA9IDIxLAogICAgICAgICAgICAgICAgIGppdHRlci5wYXJhbXMgPSBsaXN0KGhlaWdodD0wLHNlZWQ9MTApLAogICAgICAgICAgICAgICAgIG91dGxpZXIuc2hhcGUgPU5BKSsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSsKICBzY2FsZV9maWxsX21hbnVhbChuYW1lICA9IlJlZ2lvbiIsCiAgICAgICAgICAgICAgICAgICAgYnJlYWtzPWMoIjEiLCIwIiksCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIlNhdGlzZmlhYmxlIiwiVW5zYXRpc2ZpYWJsZSIpLAogICAgICAgICAgICAgICAgICAgIHZhbHVlcz1jKCIjOTBCRTZEIiwiI0Y5NDE0NCIpKSsKICB4bGFiKCJUeXBpY2FsIENhc2UgQ29tcGxleGl0eSAoVENDKSIpKwogIHlsYWIoIlRpbWUtb24tdGFzayIpKwogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgeWxpbSgwLjE1LDEpCgpwbG8KZ2dzYXZlKHBhc3RlMChmb2xkZXJPdXRfZmlndXJlcywiL1RDQ19TQVRfdGltZS5wZGYiKSxwbG8sd2lkdGggPSA3LGhlaWdodCA9Nix1bml0cz0iaW4iKQpgYGAKCiMjIyBTYXRzaWZpYWJpbGl0eSBhbmQgVENDCgpgYGB7ciAsIGZpZy5hbGlnbj0nY2VudGVyJ30KCmRhdGFJbnB1dD1kYXRhVHJpYWxfU0FUX1RpbWUgJT4lIGdyb3VwX2J5KHBoYXNlVCxzb2wscElEKSU+JXN1bW1hcmlzZSh0aW1lU3BlbnQxPW1lYW4odGltZVNwZW50KSklPiV1bmdyb3VwKCklPiVncm91cF9ieShzb2wscGhhc2VUKSU+JXN1bW1hcmlzZSh0aW1lU3BlbnQ9bWVhbih0aW1lU3BlbnQxKSxzZT1zZSh0aW1lU3BlbnQxKSklPiV1bmdyb3VwKCkKCnNvbF9uYW1lcyA8LSBjKAogICAgICAgICAgICAgICAgICAgIGAwYCA9ICJDb3JyZWN0IGFuc3dlcjogTk8iLAogICAgICAgICAgICAgICAgICAgIGAxYCA9ICJDb3JyZWN0IGFuc3dlcjogWUVTIiwKICAgICAgICAgICAgICAgICAgICBgMmAgPSAiSWYgdGhpcyBpcyBoZXJlIGl0IG1lYW5zIGRhdGEgbm90IGZpbHRlcmVkIgogICAgICAgICAgICAgICAgICAgICkKCnBsbz1nZ3Bsb3QoZGF0YT1kYXRhSW5wdXQsIGFlcyh5PXRpbWVTcGVudCwgeD1hcy5mYWN0b3IoYXMubG9naWNhbChwaGFzZVQpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IHJvdW5kKHRpbWVTcGVudCxkaWdpdHMgPSAxKSxncm91cD0xKSkgKwogIGdlb21fbGluZSgpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49dGltZVNwZW50LXNlLCB5bWF4PXRpbWVTcGVudCtzZSksIHdpZHRoPS4xKSArCiAgZ2VvbV9wb2ludChzaGFwZT0yMSwgc2l6ZT0zLCBmaWxsPSJ3aGl0ZSIpKwogIGxhYnModGl0bGU9IlRpbWUgU3BlbnQgc2VncmVnYXRlZCBieSBzb2x2YWJpbGl0eSIseD0iSW4gUGhhc2UgVHJhbnNpdGlvbj8iLHk9IlRpbWUgU3BlbnQiKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9MCxoanVzdD0wLjUpKSsKICBnZW9tX3RleHQoaGp1c3Q9LTAuNSwgY29sb3VyPSJibGFjayIpKwogIGZhY2V0X2dyaWQoLn5zb2wsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoc29sX25hbWVzKSkKCm91dHB1dE5hbWUgPSAic2F0X3RpbWVfMDNfZyIKcGxvdEV4cG9ydChwbG8sb3V0cHV0TmFtZSxmb2xkZXJPdXRfZmlndXJlcykKYGBgCgpgYGB7cn0KZGF0YUlucHV0PSBkYXRhVHJpYWxfU0FUX1RpbWUKI2xvZ2lzdGljIHdpdGggcmFuZG9tIGVmZmVjdHMgKGludGVyY2VwdCkKZGF0YUlucHV0JHNvbCA9YXMuZmFjdG9yKGRhdGFJbnB1dCRzb2wpCmRhdGFJbnB1dCRwaGFzZVQgPSBhcy5mYWN0b3IoZGF0YUlucHV0JHBoYXNlVCkKCiMgVFRUT0RPCnJhbmRvbUludGVyY2VwdCA9IGJybTIodGltZVNwZW50X3BjdCB8IGNlbnMoY2Vuc29yZWRfdGltZSkgfiBwaGFzZVQgKyBzb2wgKyBwaGFzZVQ6c29sICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LCAKICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCwgaXRlciA9IGl0ZXJzX2hpZ2gpCgp0aXRsZT0iTGluZWFyIHJlZ3Jlc3Npb25zIgp0YWJsZU5hbWU9InNhdF90aW1lXzAzX3IiCnNhdmVfc3VtbWFyaXNlX21vZGVsKHJhbmRvbUludGVyY2VwdCwgdGFibGVOYW1lKQoKYGBgCgpNYXJnaW5hbCBFZmZlY3RzCgpgYGB7cn0KI21hcmdpbmFsX2VmZmVjdHMocmFuZG9tSW50ZXJjZXB0LCBhc2s9RkFMU0UpCnBsb3QobWFyZ2luYWxfZWZmZWN0cyhhbGxNb2RlbHNbWyJzYXRfdGltZV8wM19yIl1dKSwgcGxvdCA9IFRSVUUsIGFzayA9IEZBTFNFKQoKYGBgCgojIyMgU2F0aXNmaWFiaWxpdHkKCmBgYHtyfQojc3QwNgpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9TQVRfVGltZQojbG9naXN0aWMgd2l0aCByYW5kb20gZWZmZWN0cyAoaW50ZXJjZXB0KQojZGF0YUlucHV0JHNvbCA9YXMuZmFjdG9yKGRhdGFJbnB1dCRzb2wpCgpyYW5kb21JbnRlcmNlcHQgPSBicm0yKHRpbWVTcGVudF9wY3QgfCBjZW5zKGNlbnNvcmVkX3RpbWUpIH4gc29sICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LCAKICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCwgaXRlciA9IGl0ZXJzX2hpZ2gpCgp0YWJsZU5hbWU9InNhdF90aW1lXzAzX3JfQiIKc2F2ZV9zdW1tYXJpc2VfbW9kZWwocmFuZG9tSW50ZXJjZXB0LCB0YWJsZU5hbWUpCgpgYGAKCiMjIyBSZWdpb24gZWZmZWN0IG9uIHRpbWUtb24tdGFzayAoQ29uc3RyYWluZWRuZXNzKQoKYGBge3IgLCBmaWcuYWxpZ249J2NlbnRlcid9CmRhdGFJbnB1dD1kYXRhVHJpYWxfU0FUX1RpbWUgIyU+JSBtdXRhdGUocmVnaW9uPXJlY29kZSh0eXBlLCBgMWA9ICdQaGFzZSBUcmFuc2l0aW9uJywgYDJgPSAnUGhhc2UgVHJhbnNpdGlvbicsIGAzYD0gJ1BoYXNlIFRyYW5zaXRpb24nLCBgNGA9J1BoYXNlIFRyYW5zaXRpb24nLCAnNSc9J092ZXJjb25zdHJhaW5lZCcsICc2Jz0nVW5kZXJjb25zdHJhaW5lZCcpKQoKZGF0YUlucHV0Mj1kYXRhSW5wdXQgJT4lIGdyb3VwX2J5KHJlZ2lvbixwSUQpJT4lc3VtbWFyaXNlKHRpbWVTcGVudDE9bWVhbih0aW1lU3BlbnQpKSU+JXVuZ3JvdXAoKSU+JWdyb3VwX2J5KHJlZ2lvbiklPiVzdW1tYXJpc2UodGltZVNwZW50PW1lYW4odGltZVNwZW50MSksc2U9c2UodGltZVNwZW50MSkpJT4ldW5ncm91cCgpCgpkYXRhSW5wdXQyJHJlZ2lvbiA8LSBmYWN0b3IoZGF0YUlucHV0MiRyZWdpb24sIGxldmVscyA9IGMoJ1VuZGVyY29uc3RyYWluZWQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1BoYXNlIFRyYW5zaXRpb24nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ092ZXJjb25zdHJhaW5lZCcpKQoKcGxvPSBnZ3Bsb3QoZGF0YT1kYXRhSW5wdXQyLCBhZXMoeT10aW1lU3BlbnQsIHg9cmVnaW9uLCBsYWJlbCA9IHJvdW5kKHRpbWVTcGVudCxkaWdpdHMgPSAxKSkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikrCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj10aW1lU3BlbnQtc2UsIHltYXg9dGltZVNwZW50K3NlKSwgd2lkdGg9LjEpKwogIGxhYnModGl0bGU9InRpbWUgU3BlbnQgYnkgcmVnaW9uIix4PSJSZWdpb24iLHk9InRpbWUgU3BlbnQiKSsKICAjY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDAuNSwxKSkrCiAgZ2VvbV90ZXh0KGhqdXN0PTAuNSx2anVzdCA9IDUsIGNvbG91cj0id2hpdGUiKSArCiAgdGhlbWVfbGlnaHQoKSsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQoKb3V0cHV0TmFtZSA9ICJzYXRfdGltZV8wNF9nIgpwbG90RXhwb3J0KHBsbyxvdXRwdXROYW1lLGZvbGRlck91dF9maWd1cmVzKQoKI1N0YXRzIHRlc3QgZm9yIHRpbWUgaW4gYW5kIG91dCBvZiBwaGFzZSB0cmFuc2l0aW9uOiBBTk9WQQpkYXRhSW5wdXQkb3ZlckNvbnN0cmFpbmVkPSAoZGF0YUlucHV0JHJlZ2lvbj09J092ZXJjb25zdHJhaW5lZCcpCmRhdGFJbnB1dCR1bmRlckNvbnN0cmFpbmVkPSAoZGF0YUlucHV0JHJlZ2lvbj09J1VuZGVyY29uc3RyYWluZWQnKQoKYGBgCgpgYGB7cn0KcmFuZG9tSW50ZXJjZXB0ID0gYnJtMih0aW1lU3BlbnRfcGN0IHwgY2VucyhjZW5zb3JlZF90aW1lKSB+IG92ZXJDb25zdHJhaW5lZCArIHVuZGVyQ29uc3RyYWluZWQgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwLCBpdGVyID0gaXRlcnNfaGlnaCkKCnRhYmxlTmFtZT0ic2F0X3RpbWVfMDRfZ19BIgpzYXZlX3N1bW1hcmlzZV9tb2RlbChyYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKCmBgYAoKSXMgdGhlcmUgYSBkaWZmZXJlbmNlIGJldHdlZW4gdGltZS1vbi10YXNrIGJldHdlZW4gdGhlIG92ZXJjb25zdHJhaW5lZCByZWdpb24gYW5kIHRoZSB1bmRlcmNvbnN0cmFpbmVkIHJlZ2lvbj8KCmBgYHtyfQpmaXQgPSBoeXBvdGhlc2lzKGFsbE1vZGVsc1tbInNhdF90aW1lXzA0X2dfQSJdXSwib3ZlckNvbnN0cmFpbmVkVFJVRT11bmRlckNvbnN0cmFpbmVkVFJVRSIsIHNlZWQ9c2VlZF9icm1zKQoKcHJpbnQoZml0KQoKaGRpKGZpdCRzYW1wbGVzLGNpPTAuOTUpCmBgYAoKIyMjIE51bWJlciBvZiBzb2x1dGlvbiB3aXRuZXNzZXMgdGhhdCBzYXRpc2Z5IHRoZSBjb25zdHJhaW50cyB7I3NhdF90aW1lX25zb2x9CgojIyMjIE5vLiB3aXRuZXNzZXMgYW5kIFRDQwoKYGBge3IgLCBmaWcuYWxpZ249J2NlbnRlcid9CmRhdGFJbnB1dD1kYXRhVHJpYWxfU0FUX1RpbWUKCiNQbG90cyBuU29sdXRpb25zICh4KSB2cy4gQWNjdXJhY3kgKHkpCmRhdGFJbnB1dDMgPSBkYXRhSW5wdXQgJT4lIGdyb3VwX2J5KG5Tb2x1dGlvbnMscElELHBoYXNlVCklPiVzdW1tYXJpc2UodGltZVNwZW50MT1tZWFuKHRpbWVTcGVudCkpJT4ldW5ncm91cCgpJT4lZ3JvdXBfYnkoblNvbHV0aW9ucyxwaGFzZVQpJT4lc3VtbWFyaXNlKHRpbWVTcGVudD1tZWFuKHRpbWVTcGVudDEpLHNlPXNlKHRpbWVTcGVudDEpKSU+JXVuZ3JvdXAoKQoKZGF0YUlucHV0MyRzb2wgPSBkYXRhSW5wdXQzJG5Tb2x1dGlvbnM+PTEKZGF0YUlucHV0MyRwaGFzZVQgPSByZWNvZGUoZGF0YUlucHV0MyRwaGFzZVQsICcwJyA9ICJMb3cgSUMiLCAnMScgPSAiSGlnaCBJQyIpCgpwbG89IGdncGxvdChkYXRhPWRhdGFJbnB1dDMsIGFlcyh5PXRpbWVTcGVudCwgeD1hcy5mYWN0b3IoblNvbHV0aW9ucykpKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj10aW1lU3BlbnQtc2UsIHltYXg9dGltZVNwZW50K3NlKSwgd2lkdGg9LjEpKwogIGdlb21fcG9pbnQoc2hhcGU9MjMsIHNpemU9MywgZmlsbD0icmVkIikrCiAgbGFicyh0aXRsZT0iVGltZSBTcGVudCBhbmQgdGhlIE51bWJlciBvZiBTb2x1dGlvbnMiLAogICAgICAgeD0iTnVtYmVyIG9mICAgU29sdXRpb25zIix5PSJUaW1lIFNwZW50IikrCiAgI2Nvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLjUsMSkpKwogIHRoZW1lX2xpZ2h0KCkrCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSxzdHJpcC50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpKwogIGZhY2V0X2dyaWQocGhhc2VUfnNvbCwgc2NhbGVzID0gImZyZWVfeCIsIHNwYWNlID0gImZyZWVfeCIpKwogIGdlb21fc21vb3RoKGRhdGE9ZGF0YUlucHV0MywgYWVzKHk9dGltZVNwZW50LCB4PW5Tb2x1dGlvbnMpLG1ldGhvZD1nbG0sCiAgICAgICAgICAgICAgc2U9RkFMU0UsZnVsbHJhbmdlPVRSVUUsbGluZXR5cGUgPSAiZGFzaGVkIikKCm91dHB1dE5hbWUgPSAic2F0X3RpbWVfMDVfZyIKcGxvdEV4cG9ydChwbG8sb3V0cHV0TmFtZSxmb2xkZXJPdXRfZmlndXJlcykKCmBgYAoKCmBgYHtyfQoKIyBGb3Igc2F0aXNmaWFibGUgaW5zdGFuY2Ugb25seQpkYXRhSW5wdXQgPSBkYXRhSW5wdXQgJT4lIGZpbHRlcihzb2w9PTEpCgpyYW5kb21JbnRlcmNlcHQgPSBicm0yKHRpbWVTcGVudF9wY3QgfCBjZW5zKGNlbnNvcmVkX3RpbWUpIH4gcGhhc2VUICsgblNvbHV0aW9ucyArIHBoYXNlVDpuU29sdXRpb25zICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LCAKICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCwgaXRlciA9IGl0ZXJzX2hpZ2gpCgp0YWJsZU5hbWU9InNhdF90aW1lXzA1X3JfQSIKc2F2ZV9zdW1tYXJpc2VfbW9kZWwocmFuZG9tSW50ZXJjZXB0LCB0YWJsZU5hbWUpCgpgYGAKClRoaXMgY2FsY3VsYXRlcyB0aGUgc2lnbmlmaWNhbmNlIG9mIHRoZSBiZXRhKHNsb3BlKSBvZiB0aGUgbnVtYmVyIG9mIHdpdG5lc3NlcyBmb3IgaW5zdGFuY2VzIHdpdGggaGlnaCBUQ0MuCgpgYGB7cn0KI1RoaXMgdmVyc2lvbiByZWNvZGVzIHBoYXNlVCB0byBPdXRwaGFzZVQsIHRvIAoKZml0ID0gaHlwb3RoZXNpcyhhbGxNb2RlbHNbWyJzYXRfdGltZV8wNV9yX0EiXV0sIm5Tb2x1dGlvbnMgKyBwaGFzZVQ6blNvbHV0aW9ucyA9IDAiLCBzZWVkPXNlZWRfYnJtcykKCiNmaXQgPSBoeXBvdGhlc2lzKHJhbmRvbUludGVyY2VwdCwiblNvbHV0aW9ucyA9IDAiLCBzZWVkPXNlZWRfYnJtcykKCnByaW50KGZpdCkKCmhkaShmaXQkc2FtcGxlcyxjaT0wLjk1KQoKI3N1bW1hcnkocmFuZG9tSW50ZXJjZXB0KQoKYGBgCgpNYXJnaW5hbCBFZmZlY3RzCgpgYGB7cn0KcGxvdChtYXJnaW5hbF9lZmZlY3RzKGFsbE1vZGVsc1tbInNhdF90aW1lXzA1X3JfQSJdXSksIHBsb3QgPSBUUlVFLCBhc2sgPSBGQUxTRSkKCmBgYAoKIyMjIyBOU29sIChSZWdyZXNzZWQgYWxvbmUpCgpgYGB7cn0KI3N0MDcKZGF0YUlucHV0PSBkYXRhVHJpYWxfU0FUX1RpbWUKZGF0YUlucHV0ID0gZGF0YUlucHV0ICU+JSBmaWx0ZXIoc29sPT0xKQojbG9naXN0aWMgd2l0aCByYW5kb20gZWZmZWN0cyAoaW50ZXJjZXB0KQojZGF0YUlucHV0JHNvbCA9YXMuZmFjdG9yKGRhdGFJbnB1dCRzb2wpCgpyYW5kb21JbnRlcmNlcHQgPSBicm0yKHRpbWVTcGVudF9wY3QgfCBjZW5zKGNlbnNvcmVkX3RpbWUpIH4gIG5Tb2x1dGlvbnMgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwLCBpdGVyID0gaXRlcnNfaGlnaCkKCnRhYmxlTmFtZT0ic2F0X3RpbWVfMDVfcl9CIgpzYXZlX3N1bW1hcmlzZV9tb2RlbChyYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKCmBgYAoKYGBge3J9CiNkYXRhSW5wdXQzCm1lYW5fYWNjID0gZGF0YUlucHV0ICU+JSBncm91cF9ieShpbnN0YW5jZU51bWJlcixuU29sdXRpb25zLCBzb2wscGhhc2VUKSAlPiUKICBzdW1tYXJpc2UoYWNjdXJhY3k9bWVhbihjb3JyZWN0KSwKICAgICAgICAgICAgdGltZVNwZW50X21lZCA9bWVkaWFuKHRpbWVTcGVudCkpIAoKbG9naXRSYW5kb21JbnRlcmNlcHQgPSBhbGxNb2RlbHNbWydzYXRfdGltZV8wNV9yX0InXV0KcHAgID0gcGxvdChjb25kaXRpb25hbF9lZmZlY3RzKGxvZ2l0UmFuZG9tSW50ZXJjZXB0LAogICAgICAgICAgIHByb2JzID0gYygwLjAyNSwwLjk3NSkpLCBwbG90ID0gRkFMU0UsIGFzayA9IEZBTFNFKQoKcHAkblNvbHV0aW9ucyArIAogIGdlb21fcG9pbnQoZGF0YT1tZWFuX2FjYyxhZXMoeCA9IG5Tb2x1dGlvbnMsIHkgPSB0aW1lU3BlbnRfbWVkL1NBVFRhc2tNYXhUaW1lKSxpbmhlcml0LmFlcyA9IEZBTFNFKQoKCmBgYAoKYGBge3J9CiMgSW1wcm92aW5nIHRoZSBwbG90CgpzaXplX2JpZyA9IDIwCnNpemVfc21hbGwgPSAxNgpzaXplX3NzID0gMTAKc2l6ZV94cyA9IDcKCnBwX3Bsb3QgPSBwcCRuU29sdXRpb25zCnBwX3Bsb3QkbGF5ZXJzW1sxXV0kZ2VvbV9wYXJhbXMkc2UgPSBGQUxTRQpwcF9wbG90JGxheWVyc1tbMV1dJGFlc19wYXJhbXMkY29sb3VyPSIjNTc3NTkwIgoKcHBfcGxvdCRsYXllcnMgPC0gYyhnZW9tX2JveHBsb3QoZGF0YT1kYXRhSW5wdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBuU29sdXRpb25zLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAgPSBuU29sdXRpb25zLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHRpbWVTcGVudF9wY3QpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFKSwKICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9wb2ludChkYXRhPW1lYW5fYWNjLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IG5Tb2x1dGlvbnMsIHkgPSB0aW1lU3BlbnRfbWVkL1NBVFRhc2tNYXhUaW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2w9YXMuZmFjdG9yKHNvbCksIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpLCBzaXplPTIuNSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5oZXJpdC5hZXMgPSBGQUxTRSksCiAgICAgICAgICAgICAgICAgICAgICAgICBwcF9wbG90JGxheWVycykKCnBsbyA9IHBwX3Bsb3QgKwogIHhsYWIoIk51bWJlciBvZiBzb2x1dGlvbiBXaXRuZXNzZXMiKSsjZXhwcmVzc2lvbihJQ1tleHBvc3RdKSkrCiAgeWxhYigiVGltZS1vbi10YXNrIikrCiAgc2NhbGVfc2hhcGVfbWFudWFsKG5hbWU9IiIsdmFsdWVzID0gYygxNywxNikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwobmFtZT0iIix2YWx1ZXMgPSBjKCIxIj0iIzkwQkU2RCIsIjAiPSIjRjk0MTQ0IikpKwogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgeWxpbSgwLCAxKSsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYygxLDMsNSw3LDkpLGxpbWl0cyA9YygwLjUsMTAuNSkpKwogIGd1aWRlcyhzaGFwZSA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzKSkpCgpwbG8KZ2dzYXZlKHBhc3RlMChmb2xkZXJPdXRfZmlndXJlcywiL053aXRfU0FUX3RpbWUucGRmIikscGxvLHdpZHRoID0gNixoZWlnaHQgPTYsdW5pdHM9ImluIikKYGBgCgpgYGB7cn0KIyBJbXByb3ZpbmcgdGhlIHBsb3QKCnNpemVfYmlnID0gMjAKc2l6ZV9zbWFsbCA9IDE2CnNpemVfc3MgPSAxMApzaXplX3hzID0gNwoKcHBfcGxvdCA9IHBwJG5Tb2x1dGlvbnMKcHBfcGxvdCRsYXllcnNbWzFdXSRnZW9tX3BhcmFtcyRzZSA9IFRSVUUKcHBfcGxvdCRsYXllcnNbWzFdXSRhZXNfcGFyYW1zJGNvbG91cj0iIzU3NzU5MCIKCnBwX3Bsb3QkbGF5ZXJzIDwtIGMoZ2VvbV9wb2ludChkYXRhPWRhdGFJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gblNvbHV0aW9ucywgeSA9IHRpbWVTcGVudF9wY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcGU9YXMuZmFjdG9yKHBoYXNlVCksIHNpemU9MC40LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFscGhhID0gMC41KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFKSwKICAgICAgICAgICAgICAgICAgICBnZW9tX3BvaW50KGRhdGE9bWVhbl9hY2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gblNvbHV0aW9ucywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSB0aW1lU3BlbnRfbWVkL1NBVFRhc2tNYXhUaW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2w9YXMuZmFjdG9yKHNvbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpLCBzaXplPTIuNSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5oZXJpdC5hZXMgPSBGQUxTRSksCiAgICAgICAgICAgICAgICAgICAgICAgICBwcF9wbG90JGxheWVycykKCgpwbG8gPSBwcF9wbG90ICsKICB4bGFiKCJOdW1iZXIgb2Ygc29sdXRpb24gV2l0bmVzc2VzIikrI2V4cHJlc3Npb24oSUNbZXhwb3N0XSkpKwogIHlsYWIoIlRpbWUtb24tdGFzayIpKwogIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lPSIiLHZhbHVlcyA9IGMoMTcsMTYpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWU9IiIsdmFsdWVzID0gYygiMSI9IiM5MEJFNkQiLCIwIj0iI0Y5NDE0NCIpKSsjYyggIiNGQzRFMDciLCIjRTdCODAwIikKICAjIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lPSJJQyIsdmFsdWVzID0gYygyLCA4KSkrCiAgIyBzY2FsZV9jb2xvcl9tYW51YWwobmFtZT0iU29sdXRpb24iLHZhbHVlcyA9IGMoInJlZCIsICJibHVlIikpKwogIHRoZW1lX2NsYXNzaWMoKSsKCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPSBzaXplX2JpZyksCiAgICAgICBheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9c2l6ZV9zbWFsbCksCiAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpKwogIHlsaW0oMCwgMSkrCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMSwzLDUsNyw5KSxsaW1pdHMgPWMoMC41LDEwLjUpKSsKICBndWlkZXMoc2hhcGUgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gMykpKQoKcGxvCmdnc2F2ZShwYXN0ZTAoZm9sZGVyT3V0X2ZpZ3VyZXMsIi9Od2l0X1NBVF90aW1lMi5wZGYiKSxwbG8sd2lkdGggPSA2LGhlaWdodCA9Nix1bml0cz0iaW4iKQpgYGAKCiMjIyBJQ19leHBvc3QgKGRpc3RhbmNlIGZyb20gdGhlIG9wdGltdW0pIHsjc2F0X3RpbWVfSUNleHBvc3R9CgpgYGB7ciwgZmlnLmFsaWduPSdjZW50ZXInfQpkYXRhSW5wdXQgPSBkYXRhVHJpYWxfU0FUX1RpbWUKIyBTdW1tYXJpc2UgdGhlIGRhdGEgdG8gcGxvdAptZWFuX2FjY3VyYWN5X3RpbWUgPSBkYXRhSW5wdXQgJT4lIAogIGdyb3VwX2J5KGluc3RhbmNlTnVtYmVyLCBzb2wsIElDZXhwb3N0LCBwaGFzZVQsIG5Tb2x1dGlvbnMpICU+JSAKICBzdW1tYXJpc2UoYWNjdXJhY3kgPSBtZWFuKGNvcnJlY3QpLCAKICAgICAgICAgICAgdGltZVNwZW50X21lZCA9IG1lZGlhbih0aW1lU3BlbnQpLAogICAgICAgICAgICB0aW1lU3BlbnQgPSBtZWFuKHRpbWVTcGVudCkpCgpnZ3Bsb3QobWVhbl9hY2N1cmFjeV90aW1lLGFlcyh4ID0gSUNleHBvc3QsIHkgPSB0aW1lU3BlbnQpKSsKICBnZW9tX3BvaW50KCkgKwogIHRoZW1lX2xpZ2h0KCkgKwogIHN0YXRfc21vb3RoKGZvcm11bGEgPSAgeSB+IEkoeF4wLjAxKSwgbWV0aG9kPSJsbSIsIHNlPSBGQUxTRSkrCiAgeGxhYigiSUNfZXhwb3N0IikrCiAgeWxhYigiVGltZSBTcGVudCIpCgpgYGAKCiMjIyMjIFVuc2F0aXNmaWFibGUgaW5zdGFuY2VzCgpgYGB7cn0KZGF0YUlucHV0ID0gZGF0YVRyaWFsX1NBVF9UaW1lICU+JSBmaWx0ZXIoc29sPT0wKQoKbW9kZWxfSUNleHBvc3QgPSBicm0yKHRpbWVTcGVudF9wY3QgfCBjZW5zKGNlbnNvcmVkX3RpbWUpIH4gSUNleHBvc3QgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoID0gMCwgaXRlciA9IGl0ZXJzX2hpZ2gpCgp0YWJsZU5hbWU9J3NhdF90aW1lX2ljZXhwb3N0JwpzYXZlX3N1bW1hcmlzZV9tb2RlbChtb2RlbF9JQ2V4cG9zdCwgdGFibGVOYW1lKQoKCmBgYAoKIyMjIyMgQWxsIGluc3RhbmNlcwoKYGBge3J9CmRhdGFJbnB1dCA9IGRhdGFUcmlhbF9TQVRfVGltZQoKbW9kZWxfSUNleHBvc3QgPSBicm0yKHRpbWVTcGVudF9wY3QgfCBjZW5zKGNlbnNvcmVkX3RpbWUpIH4gSUNleHBvc3QgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoID0gMCwgaXRlciA9IGl0ZXJzX2hpZ2gpCgp0YWJsZU5hbWU9J3NhdF90aW1lX2ljZXhwb3N0MicKc2F2ZV9zdW1tYXJpc2VfbW9kZWwobW9kZWxfSUNleHBvc3QsIHRhYmxlTmFtZSkKYGBgCgpNYXJnaW5hbCBFZmZlY3RzCgpgYGB7cn0KbWVhbl9hY2N1cmFjeV90aW1lJGNvcnJlY3Q9IG1lYW5fYWNjdXJhY3lfdGltZSRhY2N1cmFjeQojbWVhbl9hY2N1cmFjeV90aW1lJElDZXhwb3N0MDUgPSBtZWFuX2FjY3VyYWN5X3RpbWUkSUNleHBvc3ReMC41Cgptb2RlbF9JQ2V4cG9zdCA9IGFsbE1vZGVsc1tbJ3NhdF90aW1lX2ljZXhwb3N0MiddXQpwcCAgPSBwbG90KGNvbmRpdGlvbmFsX2VmZmVjdHMobW9kZWxfSUNleHBvc3QpLCBwbG90ID0gRkFMU0UsIGFzayA9IEZBTFNFKQoKcHAkSUNleHBvc3QgKyAKICBnZW9tX3BvaW50KGRhdGE9bWVhbl9hY2N1cmFjeV90aW1lLGFlcyh4ID0gSUNleHBvc3QsIHkgPSB0aW1lU3BlbnQvU0FUVGFza01heFRpbWUpLGluaGVyaXQuYWVzID0gRkFMU0UpCmBgYAoKYGBge3J9CiMgSW1wcm92aW5nIHRoZSBwbG90IG9wdGlvbiAyCgpwcF9wbG90ID0gcHAkSUNleHBvc3QKcHBfcGxvdCRsYXllcnNbWzFdXSRnZW9tX3BhcmFtcyRzZSA9IFRSVUUKcHBfcGxvdCRsYXllcnNbWzFdXSRhZXNfcGFyYW1zJGNvbG91cj0iIzU3NzU5MCIKCnBwX3Bsb3QkbGF5ZXJzIDwtIGMoZ2VvbV9wb2ludChkYXRhPWRhdGFJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gSUNleHBvc3QsIHkgPSB0aW1lU3BlbnRfcGN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpLCBzaXplPTAuNCwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sPWFzLmZhY3Rvcihzb2wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFscGhhID0gMC4yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFKSwKICAgICAgICAgICAgICAgICAgICBnZW9tX3BvaW50KGRhdGE9bWVhbl9hY2N1cmFjeV90aW1lLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IElDZXhwb3N0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeSA9IHRpbWVTcGVudF9tZWQvU0FUVGFza01heFRpbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbD1hcy5mYWN0b3Ioc29sKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcGU9YXMuZmFjdG9yKHBoYXNlVCksIHNpemU9Mi41KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFKSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBwX3Bsb3QkbGF5ZXJzKQoKc2l6ZV9iaWcgPSAyMApzaXplX3NtYWxsID0gMTYKc2l6ZV9zcyA9IDEwCnNpemVfeHMgPSA3CgpwbG8gPSBwcF9wbG90ICsKICB4bGFiKCJJbnN0YW5jZSBDb21wbGV4aXR5IChJQykiKSsjZXhwcmVzc2lvbihJQ1tleHBvc3RdKSkrCiAgeWxhYigiVGltZS1vbi10YXNrIikrCiAgc2NhbGVfc2hhcGVfbWFudWFsKG5hbWU9IiIsdmFsdWVzID0gYygxNywxNikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwobmFtZT0iIix2YWx1ZXMgPSBjKCIxIj0iIzkwQkU2RCIsIjAiPSIjRjk0MTQ0IikpKyNjKCAiI0ZDNEUwNyIsIiNFN0I4MDAiKQogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgeWxpbSgwLCAxLjEpKwogIHNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBjKDAsMC4yNSwwLjUsMC43NSwxKSkrCiAgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMpKSkKCnBsbwpnZ3NhdmUocGFzdGUwKGZvbGRlck91dF9maWd1cmVzLCIvSUNfU0FUX3RpbWUxLnBkZiIpLHBsbyx3aWR0aCA9IDYsaGVpZ2h0ID02LHVuaXRzPSJpbiIpCgpgYGAKCiMjIFRpbWUtb24tdGFzayBhbmQgQWNjdXJhY3kKCmBgYHtyLCBmaWcuYWxpZ249J2NlbnRlcid9CgpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9TQVRfVGltZSAlPiUgZ3JvdXBfYnkoY29ycmVjdCxwSUQpICU+JSBzdW1tYXJpc2UodGltZVNwZW50TWVhbnM9bWVhbih0aW1lU3BlbnQpKSAlPiUgdW5ncm91cCgpICU+JSBncm91cF9ieShjb3JyZWN0KSAlPiUKICBzdW1tYXJpc2UodGltZT1tZWFuKHRpbWVTcGVudE1lYW5zKSxzZT1zZSh0aW1lU3BlbnRNZWFucykpJT4ldW5ncm91cCgpCgpwbG8gPSBnZ3Bsb3QoZGF0YT1kYXRhSW5wdXQsIGFlcyh5PXRpbWUsIHg9YXMuZmFjdG9yKGFzLmxvZ2ljYWwoY29ycmVjdCkpLCBsYWJlbCA9IHJvdW5kKHRpbWUsZGlnaXRzID0gMiksZ3JvdXA9MSkpICsKICBnZW9tX2xpbmUoKSsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPXRpbWUtc2UsIHltYXg9dGltZStzZSksIHdpZHRoPS4xKSArCiAgZ2VvbV9wb2ludChzaGFwZT0yMSwgc2l6ZT0zLCBmaWxsPSJ3aGl0ZSIpKwogIGxhYnModGl0bGU9IlRpbWUgU3BlbnQgb24gQ29ycmVjdC9JbmNvcnJlY3QgaW5zdGFuY2VzIix4PSJBbnN3ZXIgQ29ycmVjdD8iLHk9IlRpbWUgU3BlbnQiKSArCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTAsaGp1c3Q9MC41KSkrCiAgZ2VvbV90ZXh0KGhqdXN0PS0wLjUsIGNvbG91cj0iYmxhY2siKQoKb3V0cHV0TmFtZSA9ICJzYXRfdGltZV8wOV9nIgpwbG90RXhwb3J0KHBsbyxvdXRwdXROYW1lLGZvbGRlck91dF9maWd1cmVzKQoKYGBgCgpgYGB7cn0KZGF0YUlucHV0ID0gZGF0YVRyaWFsX1NBVF9UaW1lCiNTdGF0cyB0ZXN0IGZvciB0aW1lIGZvciBjb3JyZWN0L2luY29ycmVjdCBhbnN3ZXJzCmxvZ2l0UmFuZG9tSW50ZXJjZXB0ID0gYnJtMihjb3JyZWN0IH4gdGltZVNwZW50X3BjdCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseT1iZXJub3VsbGkobGluaz0ibG9naXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwKQoKCnRhYmxlTmFtZT0ic2F0X3RpbWVfMDlfciIKc2F2ZV9zdW1tYXJpc2VfbW9kZWwobG9naXRSYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKYGBgCgoKIyMgTnVtYmVyIG9mIENsaWNrcwoKIyMjIyBTYXRpc2ZpYWJpbGl0eQoKYGBge3IgLCBmaWcuYWxpZ249J2NlbnRlcid9CmRhdGFJbnB1dD1kYXRhVHJpYWxfU0FUX2NsaWNrcwoKIyBCT1hQTE9UCnBsbz0gZ2dwbG90KGRhdGE9ZGF0YUlucHV0LCBhZXMoeT1uX2NsaWNrcywgeD1yZWdpb24sIGxhYmVsID0gcm91bmQobl9jbGlja3MsZGlnaXRzID0gMCkpKSArCiAgZ2VvbV9ib3hwbG90KCkrCiAgbGFicyh4PSJSZWdpb24iLHk9Im5fY2xpY2tzIikrCiAgI2Nvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLjUsMSkpKwogIGdlb21fdGV4dChoanVzdD0wLjUsdmp1c3QgPSA1LCBjb2xvdXI9IndoaXRlIikgKwogIHRoZW1lX2xpZ2h0KCkrCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkrCiAgZmFjZXRfZ3JpZCgufnNvbCkKCgpvdXRwdXROYW1lID0gJ3NhdF9hY2NfMDRfZycKcGxvdEV4cG9ydChwbG8sb3V0cHV0TmFtZSxmb2xkZXJPdXRfZmlndXJlcykKCmBgYAoKTmljZSBQbG90OgoKYGBge3J9CnNpemVfYmlnID0gMjAKc2l6ZV9zbWFsbCA9IDE2CnNpemVfc3MgPSAxMApzaXplX3hzID0gNwoKZGF0YUlucHV0MiA9IGRhdGFUcmlhbF9TQVRfY2xpY2tzICU+JSAKICBtdXRhdGUocmVnaW9uID0gZmN0X3JlbGV2ZWwocmVnaW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5kZXJjb25zdHJhaW5lZCIsICJQaGFzZSBUcmFuc2l0aW9uIiwgIk92ZXJjb25zdHJhaW5lZCIpKSU+JSAKICBtdXRhdGUoc29sPSBhcy5mYWN0b3Ioc29sKSkgJT4lIAogIG11dGF0ZShzb2wgPSBmY3RfcmVsZXZlbChzb2wsIjEiLCAiMCIpKQoKZGF0YUlucHV0MyA9IGRhdGFJbnB1dDIgJT4lIAogIGdyb3VwX2J5KGluc3RhbmNlTnVtYmVyLHJlZ2lvbixzb2wpICU+JSAKICBzdW1tYXJpc2Uobl9jbGlja3M9bWVhbihuX2NsaWNrcykpCgpwbG8gPSBnZ3Bsb3QoZGF0YUlucHV0MyxhZXMoeD1yZWdpb24seT1uX2NsaWNrcyxmaWxsPXNvbCkpKwogICMgZ2VvbV9ib3hqaXR0ZXIoYWVzKGZpbGw9cmVnaW9uKSxqaXR0ZXIuY29sb3IgPSBOQSxqaXR0ZXIuc2hhcGUgPSAyMSkrCiAgZ2VvbV9ib3hqaXR0ZXIoaml0dGVyLmNvbG9yID0gTkEsaml0dGVyLnNoYXBlID0gMjEsCiAgICAgICAgICAgICAgICAgaml0dGVyLnBhcmFtcyA9IGxpc3QoaGVpZ2h0PTAsc2VlZD0xMCksCiAgICAgICAgICAgICAgICAgb3V0bGllci5zaGFwZT0gTkEpKwogICAgICAgICAgICAgICAgICMsb3V0bGllci5zaGFwZSA9IDQsIG91dGxpZXIuc2l6ZT0wLjkpKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpKwogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgID0iUmVnaW9uIiwKICAgICAgICAgICAgICAgICAgICBicmVha3M9YygiMSIsIjAiKSwKICAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiU2F0aXNmaWFibGUiLCJVbnNhdGlzZmlhYmxlIiksCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzPWMoIiM5MEJFNkQiLCIjRjk0MTQ0IikpKwogIHhsYWIoIlR5cGljYWwgQ2FzZSBDb21wbGV4aXR5IChUQ0MpIikrCiAgeWxhYigiTnVtYmVyIG9mIGNsaWNrcyIpKwogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMpKSkrCiAgeWxpbSgwLDIwKQoKCnBsbwpnZ3NhdmUocGFzdGUwKGZvbGRlck91dF9maWd1cmVzLCIvVENDX1NBVF9uY2xpY2tzLnBkZiIpLHBsbyx3aWR0aCA9IDcsaGVpZ2h0ID02LHVuaXRzPSJpbiIpCmBgYAoKYGBge3J9CiNMb2dpc3RpYyBSZWdyZXNzaW9uIGZvciBJbi9PdXQgUGhhc2UgdHJhbnNpdGlvbgpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9TQVRfY2xpY2tzCgojbG9naXN0aWMgd2l0aCByYW5kb20gZWZmZWN0cyAoaW50ZXJjZXB0KQojIFRUVE9ETwpyYW5kb21JbnRlcmNlcHQgPSBicm0yKG5fY2xpY2tzfCBjZW5zKGNlbnNvcmVkX2NsaWNrcykgfiBzb2wgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwLCBpdGVyID0gaXRlcnNfaGlnaCkKCnRhYmxlTmFtZT0ic2F0X2NsaWNrc18wMV9yIgpzYXZlX3N1bW1hcmlzZV9tb2RlbChyYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKYGBgCgojIyMjIFRDQwoKYGBge3J9CiNMb2dpc3RpYyBSZWdyZXNzaW9uIGZvciBJbi9PdXQgUGhhc2UgdHJhbnNpdGlvbgpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9TQVRfY2xpY2tzCgojbG9naXN0aWMgd2l0aCByYW5kb20gZWZmZWN0cyAoaW50ZXJjZXB0KQojIFRUVE9ETwpyYW5kb21JbnRlcmNlcHQgPSBicm0yKG5fY2xpY2tzfCBjZW5zKGNlbnNvcmVkX2NsaWNrcykgfiBwaGFzZVQgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwLCBpdGVyID0gaXRlcnNfaGlnaCkKCnRhYmxlTmFtZT0ic2F0X2NsaWNrc18wMl9yIgpzYXZlX3N1bW1hcmlzZV9tb2RlbChyYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKYGBgCgojIyMjIyBBbmQgU2F0aXNmaWFiaWxpdHkKCmBgYHtyfQpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9TQVRfY2xpY2tzCgojbG9naXN0aWMgd2l0aCByYW5kb20gZWZmZWN0cyAoaW50ZXJjZXB0KQpkYXRhSW5wdXQkcGhhc2VUID0gYXMuZmFjdG9yKGRhdGFJbnB1dCRwaGFzZVQpCmRhdGFJbnB1dCRzb2wgPSBhcy5mYWN0b3IoZGF0YUlucHV0JHNvbCkKcmFuZG9tSW50ZXJjZXB0ID0gYnJtMihuX2NsaWNrc3wgY2VucyhjZW5zb3JlZF9jbGlja3MpIH4gcGhhc2VUICsgc29sICsgcGhhc2VUOnNvbCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwgCiAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywgcmVmcmVzaCA9IDAsIGl0ZXIgPSBpdGVyc19oaWdoKQoKdGFibGVOYW1lPSJzYXRfY2xpY2tzXzAyQl9yIgpzYXZlX3N1bW1hcmlzZV9tb2RlbChyYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKYGBgCgpgYGB7cn0KcHAgID0gcGxvdChjb25kaXRpb25hbF9lZmZlY3RzKGFsbE1vZGVsc1tbInNhdF9jbGlja3NfMDJCX3IiXV0pLCBwbG90ID0gVFJVRSwgYXNrID0gRkFMU0UpCmBgYAoKIyMjIyBJQ2V4cG9zdAoKYGBge3J9CiNMb2dpc3RpYyBSZWdyZXNzaW9uIGZvciBJbi9PdXQgUGhhc2UgdHJhbnNpdGlvbgpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9TQVRfY2xpY2tzCgojbG9naXN0aWMgd2l0aCByYW5kb20gZWZmZWN0cyAoaW50ZXJjZXB0KQpyYW5kb21JbnRlcmNlcHQgPSBicm0yKG5fY2xpY2tzfCBjZW5zKGNlbnNvcmVkX2NsaWNrcykgfiBJQ2V4cG9zdCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwgCiAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywgcmVmcmVzaCA9IDAsIGl0ZXIgPSBpdGVyc19oaWdoKQoKdGFibGVOYW1lPSJzYXRfY2xpY2tzXzAzX3IiCnNhdmVfc3VtbWFyaXNlX21vZGVsKHJhbmRvbUludGVyY2VwdCwgdGFibGVOYW1lKQpgYGAKCmBgYHtyfQpkYXRhSW5wdXQgPSBkYXRhVHJpYWxfU0FUX2NsaWNrcwojIFN1bW1hcmlzZSB0aGUgZGF0YSB0byBwbG90Cm1lYW5fbmNsaWNrcyA9IGRhdGFJbnB1dCAlPiUgCiAgZ3JvdXBfYnkoaW5zdGFuY2VOdW1iZXIsIHNvbCwgSUNleHBvc3QsIHBoYXNlVCwgblNvbHV0aW9ucykgJT4lIAogIHN1bW1hcmlzZShuX2NsaWNrcyA9IG1lZGlhbihuX2NsaWNrcykpCgptb2RlbF9JQ2V4cG9zdCA9IGFsbE1vZGVsc1tbInNhdF9jbGlja3NfMDNfciJdXQpwcCAgPSBwbG90KGNvbmRpdGlvbmFsX2VmZmVjdHMobW9kZWxfSUNleHBvc3QpLCBwbG90ID0gRkFMU0UsIGFzayA9IEZBTFNFKQoKcHAkSUNleHBvc3QgKwogIGdlb21fcG9pbnQoZGF0YT1tZWFuX25jbGlja3MsYWVzKHggPSBJQ2V4cG9zdCwgeSA9bl9jbGlja3MpLGluaGVyaXQuYWVzID0gRkFMU0UpCmBgYAoKYGBge3J9CiMgSW1wcm92aW5nIHRoZSBwbG90CiMgSW1wcm92aW5nIHRoZSBwbG90CnNpemVfYmlnID0gMjAKc2l6ZV9zbWFsbCA9IDE2CnNpemVfc3MgPSAxMApzaXplX3hzID0gNwoKcHBfcGxvdCA9IHBwJElDZXhwb3N0CnBwX3Bsb3QkbGF5ZXJzW1sxXV0kZ2VvbV9wYXJhbXMkc2UgPSBGQUxTRQpwcF9wbG90JGxheWVyc1tbMV1dJGFlc19wYXJhbXMkY29sb3VyPSIjNTc3NTkwIgoKcHBfcGxvdCRsYXllcnMgPC0gYyhnZW9tX3BvaW50KGRhdGE9bWVhbl9uY2xpY2tzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBJQ2V4cG9zdCwgeSA9IG5fY2xpY2tzLCBjb2w9YXMuZmFjdG9yKHNvbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcGU9YXMuZmFjdG9yKHBoYXNlVCksIHNpemU9Mi41KSwgaW5oZXJpdC5hZXMgPSBGQUxTRSksCiAgICAgICAgICAgICAgICAgICAgICAgICBwcF9wbG90JGxheWVycykKCgpwbG8gPSBwcF9wbG90ICsKICB4bGFiKCJJbnN0YW5jZSBDb21wbGV4aXR5IChJQykiKSsjZXhwcmVzc2lvbihJQ1tleHBvc3RdKSkrCiAgeWxhYigiTnVtYmVyIG9mIENsaWNrcyIpKwogIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lPSIiLHZhbHVlcyA9IGMoMTcsMTYpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWU9IiIsdmFsdWVzID0gYygiMSI9IiM5MEJFNkQiLCIwIj0iI0Y5NDE0NCIpKSsKICB0aGVtZV9jbGFzc2ljKCkrCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPSBzaXplX2JpZyksCiAgICAgICBheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9c2l6ZV9zbWFsbCksCiAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpKwogIGd1aWRlcyhzaGFwZSA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzKSkpCgpwbG8KZ2dzYXZlKHBhc3RlMChmb2xkZXJPdXRfZmlndXJlcywiL0lDX1NBVF9uY2xpY2tzLnBkZiIpLHBsbyx3aWR0aCA9IDYsaGVpZ2h0ID02LHVuaXRzPSJpbiIpCmBgYAoKT25seSBVbnNhdGlzZmlhYmxlOgoKYGBge3J9CiNMb2dpc3RpYyBSZWdyZXNzaW9uIGZvciBJbi9PdXQgUGhhc2UgdHJhbnNpdGlvbgpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9TQVRfY2xpY2tzICU+JSBmaWx0ZXIoc29sPT0wKQoKI2xvZ2lzdGljIHdpdGggcmFuZG9tIGVmZmVjdHMgKGludGVyY2VwdCkKIyBUVFRPRE8KcmFuZG9tSW50ZXJjZXB0ID0gYnJtMihuX2NsaWNrc3wgY2VucyhjZW5zb3JlZF9jbGlja3MpIH4gSUNleHBvc3QgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwLCBpdGVyID0gaXRlcnNfaGlnaCkKCnRhYmxlTmFtZT0ic2F0X2NsaWNrc18wM19yQiIKc2F2ZV9zdW1tYXJpc2VfbW9kZWwocmFuZG9tSW50ZXJjZXB0LCB0YWJsZU5hbWUpCmBgYAoKYGBge3J9CmRhdGFJbnB1dD0gZGF0YVRyaWFsX1NBVF9jbGlja3MgIyU+JSBmaWx0ZXIoc29sPT0wKQojIFN1bW1hcmlzZSB0aGUgZGF0YSB0byBwbG90Cm1lYW5fbmNsaWNrcyA9IGRhdGFJbnB1dCAlPiUgCiAgZ3JvdXBfYnkoaW5zdGFuY2VOdW1iZXIsIHNvbCwgSUNleHBvc3QsIHBoYXNlVCwgblNvbHV0aW9ucykgJT4lIAogIHN1bW1hcmlzZShuX2NsaWNrcyA9IG1lZGlhbihuX2NsaWNrcykpCgptb2RlbF9JQ2V4cG9zdCA9IGFsbE1vZGVsc1tbInNhdF9jbGlja3NfMDNfckIiXV0KcHAgID0gcGxvdChjb25kaXRpb25hbF9lZmZlY3RzKG1vZGVsX0lDZXhwb3N0KSwgcGxvdCA9IEZBTFNFLCBhc2sgPSBGQUxTRSkKCnBwJElDZXhwb3N0ICsKICBnZW9tX3BvaW50KGRhdGE9bWVhbl9uY2xpY2tzLGFlcyh4ID0gSUNleHBvc3QsIHkgPW5fY2xpY2tzKSxpbmhlcml0LmFlcyA9IEZBTFNFKQpgYGAKCmBgYHtyfQojIEltcHJvdmluZyB0aGUgcGxvdAojIEltcHJvdmluZyB0aGUgcGxvdApzaXplX2JpZyA9IDIwCnNpemVfc21hbGwgPSAxNgpzaXplX3NzID0gMTAKc2l6ZV94cyA9IDcKCnBwX3Bsb3QgPSBwcCRJQ2V4cG9zdApwcF9wbG90JGxheWVyc1tbMV1dJGdlb21fcGFyYW1zJHNlID0gRkFMU0UKcHBfcGxvdCRsYXllcnNbWzFdXSRhZXNfcGFyYW1zJGNvbG91cj0iIzU3NzU5MCIKCnBwX3Bsb3QkbGF5ZXJzIDwtIGMoZ2VvbV9qaXR0ZXIoZGF0YT1kYXRhSW5wdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IElDZXhwb3N0LCB5ID0gbl9jbGlja3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcGU9YXMuZmFjdG9yKHBoYXNlVCksIHNpemU9MC40LAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2w9YXMuZmFjdG9yKHNvbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWxwaGEgPSAwLjIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaGVyaXQuYWVzID0gRkFMU0UsaGVpZ2h0PTAuMiksCiAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fcG9pbnQoZGF0YT1tZWFuX25jbGlja3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gSUNleHBvc3QsIHkgPSBuX2NsaWNrcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sPWFzLmZhY3Rvcihzb2wpLCBzaGFwZT1hcy5mYWN0b3IocGhhc2VUKSwgc2l6ZT0yLjUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaGVyaXQuYWVzID0gRkFMU0UpLAogICAgICAgICAgICAgICAgICAgICAgICAgcHBfcGxvdCRsYXllcnMpCgpwbG8gPSBwcF9wbG90ICsKICB4bGFiKCJJbnN0YW5jZSBDb21wbGV4aXR5IChJQykiKSsjZXhwcmVzc2lvbihJQ1tleHBvc3RdKSkrCiAgeWxhYigiTnVtYmVyIG9mIENsaWNrcyIpKwogIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lPSIiLHZhbHVlcyA9IGMoMTcsMTYpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWU9IiIsdmFsdWVzID0gYygiMSI9IiM5MEJFNkQiLCIwIj0iI0Y5NDE0NCIpKSsKICB0aGVtZV9jbGFzc2ljKCkrCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPSBzaXplX2JpZyksCiAgICAgICBheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9c2l6ZV9zbWFsbCksCiAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpKwogIGd1aWRlcyhzaGFwZSA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzKSkpKyAKICB4bGltKDAsMC4wOSkKCnBsbwpnZ3NhdmUocGFzdGUwKGZvbGRlck91dF9maWd1cmVzLCIvSUNfU0FUX25jbGlja3NfdW5zYXQucGRmIikscGxvLHdpZHRoID0gNixoZWlnaHQgPTYsdW5pdHM9ImluIikKYGBgCgojIyMjIyBBbmQgU2F0aXNmaWFiaWxpdHkKCmBgYHtyfQpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9TQVRfY2xpY2tzCgojbG9naXN0aWMgd2l0aCByYW5kb20gZWZmZWN0cyAoaW50ZXJjZXB0KQpkYXRhSW5wdXQkdW5zb2wgPSBhYnMoZGF0YUlucHV0JHNvbC0xKQpyYW5kb21JbnRlcmNlcHQgPSBicm0yKG5fY2xpY2tzfCBjZW5zKGNlbnNvcmVkX2NsaWNrcykgfiB1bnNvbCArIHVuc29sOklDZXhwb3N0ICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LCAKICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCwgaXRlciA9IGl0ZXJzX2hpZ2gpCgp0YWJsZU5hbWU9InNhdF9jbGlja3NfMDNfckMiCnNhdmVfc3VtbWFyaXNlX21vZGVsKHJhbmRvbUludGVyY2VwdCwgdGFibGVOYW1lKQpgYGAKCmBgYHtyfQpwcCAgPSBwbG90KGNvbmRpdGlvbmFsX2VmZmVjdHMoYWxsTW9kZWxzW1sic2F0X2NsaWNrc18wM19yQyJdXSksIHBsb3QgPSBUUlVFLCBhc2sgPSBGQUxTRSkKYGBgCgojIyMjIE5zb2x1dGlvbnMKCmBgYHtyfQpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9TQVRfY2xpY2tzCgojbG9naXN0aWMgd2l0aCByYW5kb20gZWZmZWN0cyAoaW50ZXJjZXB0KQojIFRUVE9ETwpyYW5kb21JbnRlcmNlcHQgPSBicm0yKG5fY2xpY2tzfCBjZW5zKGNlbnNvcmVkX2NsaWNrcykgfiBuU29sdXRpb25zICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LCAKICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCwgaXRlciA9IGl0ZXJzX2hpZ2gpCgp0YWJsZU5hbWU9InNhdF9jbGlja3NfMDRfciIKc2F2ZV9zdW1tYXJpc2VfbW9kZWwocmFuZG9tSW50ZXJjZXB0LCB0YWJsZU5hbWUpCmBgYAoKT25seSBTYXRpc2ZpYWJsZToKCmBgYHtyfQpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9TQVRfY2xpY2tzICU+JSBmaWx0ZXIoc29sPT0xKQoKI2xvZ2lzdGljIHdpdGggcmFuZG9tIGVmZmVjdHMgKGludGVyY2VwdCkKIyBUVFRPRE8KcmFuZG9tSW50ZXJjZXB0ID0gYnJtMihuX2NsaWNrc3wgY2VucyhjZW5zb3JlZF9jbGlja3MpIH4gblNvbHV0aW9ucyArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwgCiAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywgcmVmcmVzaCA9IDAsIGl0ZXIgPSBpdGVyc19oaWdoKQoKdGFibGVOYW1lPSJzYXRfY2xpY2tzXzA0X3JCIgpzYXZlX3N1bW1hcmlzZV9tb2RlbChyYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKYGBgCgpgYGB7cn0KI2RhdGFJbnB1dCA9IGRhdGFUcmlhbF9TQVRfY2xpY2tzCiMgU3VtbWFyaXNlIHRoZSBkYXRhIHRvIHBsb3QKbWVhbl9uY2xpY2tzID0gZGF0YUlucHV0ICU+JSAKICBncm91cF9ieShpbnN0YW5jZU51bWJlciwgc29sLCBJQ2V4cG9zdCwgcGhhc2VULCBuU29sdXRpb25zKSAlPiUgCiAgc3VtbWFyaXNlKG5fY2xpY2tzID0gbWVkaWFuKG5fY2xpY2tzKSkKCm1vZGVsX0lDZXhwb3N0ID0gYWxsTW9kZWxzW1sic2F0X2NsaWNrc18wNF9yQiJdXQpwcCAgPSBwbG90KGNvbmRpdGlvbmFsX2VmZmVjdHMobW9kZWxfSUNleHBvc3QpLCBwbG90ID0gRkFMU0UsIGFzayA9IEZBTFNFKQoKcHAkblNvbHV0aW9ucyArCiAgZ2VvbV9wb2ludChkYXRhPW1lYW5fbmNsaWNrcyxhZXMoeCA9IG5Tb2x1dGlvbnMsIHkgPW5fY2xpY2tzKSxpbmhlcml0LmFlcyA9IEZBTFNFKQpgYGAKCmBgYHtyfQojIEltcHJvdmluZyB0aGUgcGxvdAojIEltcHJvdmluZyB0aGUgcGxvdApzaXplX2JpZyA9IDIwCnNpemVfc21hbGwgPSAxNgpzaXplX3NzID0gMTAKc2l6ZV94cyA9IDcKCnBwX3Bsb3QgPSBwcCRuU29sdXRpb25zCnBwX3Bsb3QkbGF5ZXJzW1sxXV0kZ2VvbV9wYXJhbXMkc2UgPSBGQUxTRQpwcF9wbG90JGxheWVyc1tbMV1dJGFlc19wYXJhbXMkY29sb3VyPSIjNTc3NTkwIgoKcHBfcGxvdCRsYXllcnMgPC0gYyhnZW9tX2ppdHRlcihkYXRhPWRhdGFJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gblNvbHV0aW9ucywgeSA9IG5fY2xpY2tzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpLCBzaXplPTAuNCwKIyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sPWFzLmZhY3Rvcihzb2wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFscGhhID0gMC4yKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFLHdpZHRoPTAuMixoZWlnaHQgPTAuMiksCiAgICAgICAgICAgICAgICAgICAgICAgIGdlb21fcG9pbnQoZGF0YT1tZWFuX25jbGlja3MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gblNvbHV0aW9ucywgeSA9IG5fY2xpY2tzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2w9YXMuZmFjdG9yKHNvbCksIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpLCBzaXplPTIuNSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5oZXJpdC5hZXMgPSBGQUxTRSksCiAgICAgICAgICAgICAgICAgICAgICAgICBwcF9wbG90JGxheWVycykKCnBsbyA9IHBwX3Bsb3QgKwogIHhsYWIoIk51bWJlciBvZiBTb2x1dGlvbiBXaXRuZXNzZXMiKSsKICB5bGFiKCJOdW1iZXIgb2YgQ2xpY2tzIikrCiAgc2NhbGVfc2hhcGVfbWFudWFsKG5hbWU9IiIsdmFsdWVzID0gYygxNywxNikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwobmFtZT0iIix2YWx1ZXMgPSBjKCIxIj0iIzkwQkU2RCIsIjAiPSIjRjk0MTQ0IikpKwogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMpKSkKCnBsbwpnZ3NhdmUocGFzdGUwKGZvbGRlck91dF9maWd1cmVzLCIvTndpdF9TQVRfbmNsaWNrcy5wZGYiKSxwbG8sd2lkdGggPSA2LGhlaWdodCA9Nix1bml0cz0iaW4iKQpgYGAKCiMgVHJhdmVsaW5nIHNhbGVzcGVyc29uIFByb2JsZW0KCiMjIEZ1bmN0aW9ucwoKYGBge3J9CmNhbGN1bGF0ZV90c3BfSUNleHBvc3QgPWZ1bmN0aW9uKG9wdCxtYXhfZGlzdCl7CiAgSUNleHBvc3QgID0gIGFicyhvcHQtIG1heF9kaXN0KS9vcHQKICByZXR1cm4oSUNleHBvc3QpCn0KYGBgCgojIyBBY2N1cmFjeQoKUmVhZCBDbGVhbiBEYXRhIHRvIGZpbGUKCmBgYHtyfQoKZGF0YVRyaWFsX1RTUD0gcmVhZF9jc3YyKGZpbGUucGF0aChkYXRhX2ZvbGRlciwiVFNQX2NsZWFuLmNzdiIpKQoKZGF0YVRyaWFsX1RTUF9UaW1lID0gcmVhZF9jc3YyKGZpbGUucGF0aChkYXRhX2ZvbGRlciwiVFNQX2NsZWFuX3RpbWUuY3N2IikpCmRhdGFUcmlhbF9UU1BfVGltZSR0aW1lU3BlbnRfcGN0ID0gZGF0YVRyaWFsX1RTUF9UaW1lJHRpbWVTcGVudC9UU1BUYXNrTWF4VGltZQoKY29sb3Jfc2NoZW1lX3NldCgicHVycGxlIikKCmRhdGFUcmlhbF9UU1AkY2Vuc29yZWRfdGltZSA9IGlmZWxzZShkYXRhVHJpYWxfVFNQJHRpbWVTcGVudCA9PSBUU1BUYXNrTWF4VGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmlnaHQiLCJub25lIikKCmRhdGFUcmlhbF9UU1BfVGltZSRjZW5zb3JlZF90aW1lID0gaWZlbHNlKGRhdGFUcmlhbF9UU1BfVGltZSR0aW1lU3BlbnQgPT0gVFNQVGFza01heFRpbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInJpZ2h0Iiwibm9uZSIpCgppbnN0YW5jZVByb3BlcnRpZXNfVFNQPSByZWFkX2NzdjIocGFzdGUwKGRhdGFfZm9sZGVyLCJpbnN0YW5jZV9wcm9wZXJ0aWVzX1RTUC5jc3YiKSkKCmluc3RhbmNlUHJvcGVydGllc19UU1AgPWluc3RhbmNlUHJvcGVydGllc19UU1AgJT4lIAogIHNlbGVjdChpbnN0YW5jZU51bWJlcixuU29sdXRpb25zLG9wdF9kaXN0YW5jZSxvcHRfdG91cixkaXN0X2Zyb21fb3B0KQoKZGF0YVRyaWFsX1RTUCA9IGxlZnRfam9pbihkYXRhVHJpYWxfVFNQLGluc3RhbmNlUHJvcGVydGllc19UU1AsIGJ5ID0gImluc3RhbmNlTnVtYmVyIikKZGF0YVRyaWFsX1RTUF9UaW1lID0gbGVmdF9qb2luKGRhdGFUcmlhbF9UU1BfVGltZSxpbnN0YW5jZVByb3BlcnRpZXNfVFNQLCBieSA9ICJpbnN0YW5jZU51bWJlciIpCgpkYXRhVHJpYWxfVFNQJElDZXhwb3N0ID0gY2FsY3VsYXRlX3RzcF9JQ2V4cG9zdChkYXRhVHJpYWxfVFNQJG9wdF9kaXN0YW5jZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVRyaWFsX1RTUCRtYXhfZGlzdGFuY2UpCgpkYXRhVHJpYWxfVFNQX1RpbWUkSUNleHBvc3QgPSBjYWxjdWxhdGVfdHNwX0lDZXhwb3N0KGRhdGFUcmlhbF9UU1BfVGltZSRvcHRfZGlzdGFuY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFUcmlhbF9UU1BfVGltZSRtYXhfZGlzdGFuY2UpCgoKZGF0YV9UU1BfY2xpY2tzID0gcmVhZF9jc3YyKGZpbGUucGF0aChkYXRhX2ZvbGRlciwiVFNQX2NsaWNrcy5jc3YiKSkKCm5DbGlja3MgPSBkYXRhX1RTUF9jbGlja3MgJT4lIGdyb3VwX2J5KHBJRCxibG9jayx0cmlhbCkgJT4lIHN1bW1hcmlzZShuX2NsaWNrcyA9bigpKQojVmlldyhuQ2xpY2tzKQoKZGF0YVRyaWFsX1RTUF9jbGlja3M9bWVyZ2UobkNsaWNrcywKICAgICAgICAgICAgICAgICAgZGF0YVRyaWFsX1RTUCwgYnk9YygicElEIiwiYmxvY2siLCJ0cmlhbCIpKQpgYGAKCmBgYHtyLCByZXN1bHRzPSdhc2lzJ30KI1N1bW1hcnkgU3RhdHMgZm9yIERlY2lzaW9uIFByb2JsZW0KZGF0YUlucHV0PWRhdGFUcmlhbF9UU1AKCmFjY3VyYWN5U3VtbWFyeSA9IGRhdGFJbnB1dCAlPiUgZ3JvdXBfYnkocElEKSAlPiUgc3VtbWFyaXNlKGFjYz1tZWFuKGNvcnJlY3QpKSAlPiUgc3VtbWFyaXNlKG1lYW49bWVhbihhY2MpLG1pbj1taW4oYWNjKSxtYXg9bWF4KGFjYyksU0Q9c2QoYWNjKSkKa2FibGUoYWNjdXJhY3lTdW1tYXJ5LCBkaWdpdHM9MiwgY2FwdGlvbiA9ICJBY2N1cmFjeSBTdW1tYXJ5IikKCmFuc3dlclN1bW1hcnkgPSBkYXRhSW5wdXQgJT4lIGdyb3VwX2J5KHBJRCkgJT4lIHN1bW1hcmlzZShhY2M9bWVhbihhbnN3ZXIpKSAlPiUgc3VtbWFyaXNlKG1lYW49bWVhbihhY2MpLG1pbj1taW4oYWNjKSxtYXg9bWF4KGFjYyksU0Q9c2QoYWNjKSkKa2FibGUoYW5zd2VyU3VtbWFyeSwgZGlnaXRzPTIsIGNhcHRpb24gPSAiUHJvcG9ydGlvbiBvZiB0aW1lcyB0aGF0IFlFUyB3YXMgc2VsZWN0ZWQgYXMgdGhlIGFuc3dlciIpCgp5ZXNOb1Byb3BvcnRpb25zID0gZGF0YUlucHV0ICU+JSBncm91cF9ieShzb2wscElEKSAlPiUgc3VtbWFyaXNlKGFjYz1tZWFuKGNvcnJlY3QpKSAlPiUgc3VtbWFyaXNlKG1lYW49bWVhbihhY2MpLG1pbj1taW4oYWNjKSxtYXg9bWF4KGFjYyksU0Q9c2QoYWNjKSkKa2FibGUoeWVzTm9Qcm9wb3J0aW9ucywgZGlnaXRzPTIsIGNhcHRpb24gPSAiQWNjdXJhY3kgQnkgU29sdXRpb24iKQoKYGBgCgojIyMgRWZmZWN0IG9mIHRyaWFsIG51bWJlciBvbiBhY2N1cmFjeQoKYGBge3J9CiNUcmlhbCAoZXhwZXJpZW5jZSBlZmZlY3QpIGVmZmVjdApkYXRhSW5wdXQ9ZGF0YVRyaWFsX1RTUAoKI1N1bW1hcnkKc3VtbWFyeUJ5QmxvY2sgPSBkYXRhSW5wdXQgJT4lIGdyb3VwX2J5KGJsb2NrLHBJRCkgJT4lIHN1bW1hcmlzZShhY2M9bWVhbihjb3JyZWN0KSkgJT4lIHN1bW1hcmlzZShtZWFuPW1lYW4oYWNjKSxtaW49bWluKGFjYyksbWF4PW1heChhY2MpLFNEPXNkKGFjYykpCmthYmxlKHN1bW1hcnlCeUJsb2NrLCBkaWdpdHM9MiwgY2FwdGlvbiA9ICJBY2N1cmFjeSBCeSBCbG9jayBOdW1iZXIiKQoKI1JlZ3Jlc3NzaW9uCmRhdGFJbnB1dCR0b3RhbFRyaWFsID0gZGF0YUlucHV0JGJsb2NrICogZGF0YUlucHV0JHRyaWFsCgpsb2dpdFJhbmRvbUludGVyY2VwdCA9IGJybTIoY29ycmVjdCB+IHRvdGFsVHJpYWwrICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseT1iZXJub3VsbGkobGluaz0ibG9naXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaCA9IDApCgp0YWJsZU5hbWU9J3RzcF9hY2NfMDFfcicKc2F2ZV9zdW1tYXJpc2VfbW9kZWwobG9naXRSYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKCmBgYAoKIyMjIFRDQwoKYGBge3IgLCBmaWcuYWxpZ249J2NlbnRlcid9CmRhdGFJbnB1dD1kYXRhVHJpYWxfVFNQICU+JSBncm91cF9ieShwaGFzZVQscElEKSU+JXN1bW1hcmlzZShhY2N1cmFjeTE9bWVhbihjb3JyZWN0KSklPiV1bmdyb3VwKCklPiVncm91cF9ieShwaGFzZVQpJT4lc3VtbWFyaXNlKGFjY3VyYWN5PW1lYW4oYWNjdXJhY3kxKSxzZT1zZShhY2N1cmFjeTEpKSU+JXVuZ3JvdXAoKQoKZGF0YUlucHV0JHBoYXNlVCA9IHJlY29kZShkYXRhSW5wdXQkcGhhc2VULCAnMCcgPSAiTG93IElDIiwgJzEnID0gIkhpZ2ggSUMiKQoKcGxvPSBnZ3Bsb3QoZGF0YT1kYXRhSW5wdXQsIGFlcyh5PWFjY3VyYWN5LCB4PWFzLmZhY3RvcihwaGFzZVQpLGxhYmVsID0gcm91bmQoYWNjdXJhY3ksZGlnaXRzID0gMikpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49YWNjdXJhY3ktc2UsIHltYXg9YWNjdXJhY3krc2UpLCB3aWR0aD0uMSkrCiAgI2dlb21fc2lnbmlmKGNvbXBhcmlzb25zID0gbGlzdChjKCJMb3cgSUMiLCJIaWdoIElDIikpLCBhbm5vdGF0aW9ucz0iKioqIiwgeV9wb3NpdGlvbiA9IDAuOTUsIHRpcF9sZW5ndGggPSAwLjAzKSsKICBsYWJzKHRpdGxlPSJBY2N1cmFjeSBJbiBhbmQgT3V0IG9mIHBoYXNlIFRyYW5zaXRpb24iLHg9Ikluc3RhbmNlIGNvbXBsZXhpdHkiLHk9IkFjY3VyYWN5IikrCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDAuNSwxKSkrCiAgZ2VvbV90ZXh0KGhqdXN0PTAuNSx2anVzdCA9IDUsIGNvbG91cj0id2hpdGUiKSsKICB0aGVtZV9saWdodCgpKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCgpvdXRwdXROYW1lID0gJ3RzcF9hY2NfMDJfZycKcGxvdEV4cG9ydChwbG8sb3V0cHV0TmFtZSxmb2xkZXJPdXRfZmlndXJlcykKCmBgYAoKYGBge3J9CiNMb2dpc3RpYyBSZWdyZXNzaW9uIGZvciBJbi9PdXQgUGhhc2UgdHJhbnNpdGlvbgpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9UU1AKCiNsb2dpc3RpYyB3aXRoIHJhbmRvbSBlZmZlY3RzIChpbnRlcmNlcHQpCmxvZ2l0UmFuZG9tSW50ZXJjZXB0ID0gYnJtMihjb3JyZWN0IH4gcGhhc2VUICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5PWJlcm5vdWxsaShsaW5rPSJsb2dpdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywgcmVmcmVzaCA9IDApCgp0YWJsZU5hbWU9J3RzcF9hY2NfMDJfcicKc2F2ZV9zdW1tYXJpc2VfbW9kZWwobG9naXRSYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKCmBgYAoKIyMjIyBQbG90IFRDQwoKYGBge3J9CmRhdGFJbnB1dCA9IGRhdGFUcmlhbF9UU1AKCmRhdGFJbnB1dCA9IGRhdGFJbnB1dCAlPiUgCiAgbXV0YXRlKHJlZ2lvbiA9IGZjdF9yZWxldmVsKHJlZ2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuZGVyY29uc3RyYWluZWQiLCAiUGhhc2UgVHJhbnNpdGlvbiIsICJPdmVyY29uc3RyYWluZWQiKSkgJT4lIAogIG11dGF0ZShzb2w9IGFzLmZhY3Rvcihzb2wpKSAlPiUgCiAgbXV0YXRlKHNvbCA9IGZjdF9yZWxldmVsKHNvbCwiMSIsICIwIikpCgpkYXRhSW5wdXQyID0gZGF0YUlucHV0ICU+JSAKICBncm91cF9ieShpbnN0YW5jZU51bWJlcixyZWdpb24sc29sKSAlPiUgCiAgc3VtbWFyaXNlKGFjY3VyYWN5PW1lYW4oY29ycmVjdCkpCgpgYGAKCmBgYHtyfQpzaXplX2JpZyA9IDIwCnNpemVfc21hbGwgPSAxNgpzaXplX3NzID0gMTAKc2l6ZV94cyA9IDcKCgpwbG8gPSBnZ3Bsb3QoZGF0YUlucHV0MixhZXMoeD1yZWdpb24seT1hY2N1cmFjeSxmaWxsPXNvbCkpKwogICMgZ2VvbV9ib3hqaXR0ZXIoYWVzKGZpbGw9cmVnaW9uKSxqaXR0ZXIuY29sb3IgPSBOQSxqaXR0ZXIuc2hhcGUgPSAyMSkrCiAgZ2VvbV9ib3hqaXR0ZXIoaml0dGVyLmNvbG9yID0gTkEsaml0dGVyLnNoYXBlID0gMjEsCiAgICAgICAgICAgICAgICAgaml0dGVyLnBhcmFtcyA9IGxpc3QoaGVpZ2h0PTAsc2VlZD0xMCksCiAgICAgICAgICAgICAgICAgb3V0bGllci5zaGFwZT0gTkEpKwogICAgICAgICAgICAgICAgICMsb3V0bGllci5zaGFwZSA9IDQsIG91dGxpZXIuc2l6ZT0wLjkpKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpKwogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgID0iUmVnaW9uIiwKICAgICAgICAgICAgICAgICAgICBicmVha3M9YygiMSIsIjAiKSwKICAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiU2F0aXNmaWFibGUiLCJVbnNhdGlzZmlhYmxlIiksCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzPWMoIiM5MEJFNkQiLCIjRjk0MTQ0IikpKwogIHhsYWIoIlR5cGljYWwgQ2FzZSBDb21wbGV4aXR5IChUQ0MpIikrCiAgeWxhYigiSHVtYW4gUGVyZm9ybWFuY2UiKSsKICB0aGVtZV9jbGFzc2ljKCkrCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPSBzaXplX2JpZyksCiAgICAgICBheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9c2l6ZV9zbWFsbCksCiAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpKwogIGd1aWRlcyhzaGFwZSA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzKSkpKwogIHlsaW0oMC4yLDEpCgoKcGxvCmdnc2F2ZShwYXN0ZTAoZm9sZGVyT3V0X2ZpZ3VyZXMsIi9UQ0NfVFNQX2FjYy5wZGYiKSxwbG8sd2lkdGggPSA3LGhlaWdodCA9Nix1bml0cz0iaW4iKQpgYGAKCiMjIyBTYXRzaWZpYWJpbGl0eSBhbmQgVENDCgpgYGB7ciAsIGZpZy5hbGlnbj0nY2VudGVyJ30KCmRhdGFJbnB1dD1kYXRhVHJpYWxfVFNQICU+JSBncm91cF9ieShwaGFzZVQsc29sLHBJRCklPiVzdW1tYXJpc2UoYWNjdXJhY3kxPW1lYW4oY29ycmVjdCkpJT4ldW5ncm91cCgpJT4lZ3JvdXBfYnkoc29sLHBoYXNlVCklPiVzdW1tYXJpc2UoYWNjdXJhY3k9bWVhbihhY2N1cmFjeTEpLHNlPXNlKGFjY3VyYWN5MSkpJT4ldW5ncm91cCgpCgpzb2xfbmFtZXMgPC0gYygKICAgICAgICAgICAgICAgICAgICBgMGAgPSAiQ29ycmVjdCBhbnN3ZXI6IE5PIiwKICAgICAgICAgICAgICAgICAgICBgMWAgPSAiQ29ycmVjdCBhbnN3ZXI6IFlFUyIsCiAgICAgICAgICAgICAgICAgICAgYDJgID0gIklmIHRoaXMgaXMgaGVyZSBpdCBtZWFucyBkYXRhIG5vdCBmaWx0ZXJlZCIKICAgICAgICAgICAgICAgICAgICApCgpwbG89Z2dwbG90KGRhdGE9ZGF0YUlucHV0LCBhZXMoeT1hY2N1cmFjeSwgeD1hcy5mYWN0b3IoYXMubG9naWNhbChwaGFzZVQpKSwgbGFiZWwgPSByb3VuZChhY2N1cmFjeSxkaWdpdHMgPSAyKSxncm91cD0xKSkgKwogIGdlb21fbGluZSgpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49YWNjdXJhY3ktc2UsIHltYXg9YWNjdXJhY3krc2UpLCB3aWR0aD0uMSkgKwogIGdlb21fcG9pbnQoc2hhcGU9MjEsIHNpemU9MywgZmlsbD0id2hpdGUiKSsKICBsYWJzKHRpdGxlPSJBY2N1cmFjeSBzZWdyZWdhdGVkIGJ5IHNvbHZhYmlsaXR5Iix4PSJJbiBQaGFzZSBUcmFuc2l0aW9uPyIseT0iQWNjdXJhY3kiKSsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9MCxoanVzdD0wLjUpKSsKICBnZW9tX3RleHQoaGp1c3Q9LTAuNSwgY29sb3VyPSJibGFjayIpKwogIGZhY2V0X2dyaWQoLn5zb2wsIGxhYmVsbGVyID0gYXNfbGFiZWxsZXIoc29sX25hbWVzKSkKCm91dHB1dE5hbWUgPSAndHNwX2FjY18wM19nJwpwbG90RXhwb3J0KHBsbyxvdXRwdXROYW1lLGZvbGRlck91dF9maWd1cmVzKQpgYGAKCmBgYHtyfQpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9UU1AKCmRhdGFJbnB1dCRwaGFzZVQgPSBhcy5mYWN0b3IoZGF0YUlucHV0JHBoYXNlVCkKZGF0YUlucHV0JHNvbCA9IGFzLmZhY3RvcihkYXRhSW5wdXQkc29sKQoKI2xvZ2lzdGljIHdpdGggcmFuZG9tIGVmZmVjdHMgKGludGVyY2VwdCkKbG9naXRSYW5kb21JbnRlcmNlcHQgPSBicm0yKGNvcnJlY3QgfiBwaGFzZVQgKyBzb2wgKyBwaGFzZVQ6c29sICsgKDF8cElEKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseT1iZXJub3VsbGkobGluaz0ibG9naXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywgcmVmcmVzaCA9IDApCgp0YWJsZU5hbWU9J3RzcF9hY2NfMDNfcicKc2F2ZV9zdW1tYXJpc2VfbW9kZWwobG9naXRSYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKCmBgYAoKTWFyZ2luYWwgZWZmZWN0cwoKYGBge3J9CnBsb3QobWFyZ2luYWxfZWZmZWN0cyhhbGxNb2RlbHNbWyd0c3BfYWNjXzAzX3InXV0pLCBwbG90ID0gVFJVRSwgYXNrID0gRkFMU0UpCgpgYGAKCkVmZmVjdCBvZiBUQ0Mgb24gc2F0aXNmaWFibGUgaW5zdGFuY2VzCgpgYGB7cn0KI3N0MDEKbW9kZWwgPSBhbGxNb2RlbHNbWyd0c3BfYWNjXzAzX3InXV0KCmZpdCA9IGh5cG90aGVzaXMobW9kZWwsInBoYXNlVDErIHBoYXNlVDE6c29sMT0wIiwgc2VlZD1zZWVkX2JybXMpCgpwcmludChmaXQpCgpoZGkoZml0JHNhbXBsZXMsY2k9MC45NSkKYGBgCgojIyMjIE9ubHkgc2F0aXNmaWFiaWxpdHkKCmBgYHtyfQpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9UU1AKZGF0YUlucHV0JHNvbCA9IGFzLmZhY3RvcihkYXRhSW5wdXQkc29sKQoKI2xvZ2lzdGljIHdpdGggcmFuZG9tIGVmZmVjdHMgKGludGVyY2VwdCkKbG9naXRSYW5kb21JbnRlcmNlcHQgPSBicm0yKGNvcnJlY3QgfiBzb2wgKyAoMXxwSUQpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5PWJlcm5vdWxsaShsaW5rPSJsb2dpdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCkKCnRhYmxlTmFtZT0ndHNwX2FjY18wM0JfcicKc2F2ZV9zdW1tYXJpc2VfbW9kZWwobG9naXRSYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKCmBgYAoKIyMjIFJlZ2lvbiBlZmZlY3Qgb24gQWNjdXJhY3kgKENvbnN0cmFpbmVkbmVzcykKCmBgYHtyICwgZmlnLmFsaWduPSdjZW50ZXInfQpkYXRhSW5wdXQ9ZGF0YVRyaWFsX1RTUAoKZGF0YUlucHV0Mj1kYXRhSW5wdXQgJT4lIGdyb3VwX2J5KHJlZ2lvbixwSUQpJT4lc3VtbWFyaXNlKGFjY3VyYWN5MT1tZWFuKGNvcnJlY3QpKSU+JXVuZ3JvdXAoKSU+JWdyb3VwX2J5KHJlZ2lvbiklPiVzdW1tYXJpc2UoYWNjdXJhY3k9bWVhbihhY2N1cmFjeTEpLHNlPXNlKGFjY3VyYWN5MSkpJT4ldW5ncm91cCgpCgpkYXRhSW5wdXQyJHJlZ2lvbiA8LSBmYWN0b3IoZGF0YUlucHV0MiRyZWdpb24sIGxldmVscyA9IGMoJ1VuZGVyY29uc3RyYWluZWQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1BoYXNlIFRyYW5zaXRpb24nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ092ZXJjb25zdHJhaW5lZCcpKQoKcGxvPSBnZ3Bsb3QoZGF0YT1kYXRhSW5wdXQyLCBhZXMoeT1hY2N1cmFjeSwgeD1yZWdpb24sIGxhYmVsID0gcm91bmQoYWNjdXJhY3ksZGlnaXRzID0gMikpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49YWNjdXJhY3ktc2UsIHltYXg9YWNjdXJhY3krc2UpLCB3aWR0aD0uMSkrCiAgbGFicyh0aXRsZT0iQWNjdXJhY3kgYnkgcmVnaW9uIix4PSJSZWdpb24iLHk9IkFjY3VyYWN5IikrCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDAuNSwxKSkrCiAgZ2VvbV90ZXh0KGhqdXN0PTAuNSx2anVzdCA9IDUsIGNvbG91cj0id2hpdGUiKSArCiAgdGhlbWVfbGlnaHQoKSsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQoKb3V0cHV0TmFtZSA9ICd0c3BfYWNjXzA0X2cnCnBsb3RFeHBvcnQocGxvLG91dHB1dE5hbWUsZm9sZGVyT3V0X2ZpZ3VyZXMpCgojU3RhdHMgdGVzdCBmb3IgdGltZSBpbiBhbmQgb3V0IG9mIHBoYXNlIHRyYW5zaXRpb246IEFOT1ZBCmRhdGFJbnB1dCRvdmVyQ29uc3RyYWluZWQ9IChkYXRhSW5wdXQkcmVnaW9uPT0nT3ZlcmNvbnN0cmFpbmVkJykKZGF0YUlucHV0JHVuZGVyQ29uc3RyYWluZWQ9IChkYXRhSW5wdXQkcmVnaW9uPT0nVW5kZXJjb25zdHJhaW5lZCcpCgpgYGAKCmBgYHtyfQpsb2dpdFJhbmRvbUludGVyY2VwdCA9IGJybTIoY29ycmVjdCB+IG92ZXJDb25zdHJhaW5lZCArIHVuZGVyQ29uc3RyYWluZWQgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHk9YmVybm91bGxpKGxpbms9ImxvZ2l0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCkKCnRhYmxlTmFtZT0ndHNwX2FjY18wNF9yX0EnCnNhdmVfc3VtbWFyaXNlX21vZGVsKGxvZ2l0UmFuZG9tSW50ZXJjZXB0LCB0YWJsZU5hbWUpCgpgYGAKCklzIHRoZXJlIGEgZGlmZmVyZW5jZSBiZXR3ZWVuIGFjY3VyYWN5IGluIHRoZSBvdmVyY29uc3RyYWluZWQgcmVnaW9uIGFuZAp0aGUgdW5kZXJjb25zdHJhaW5lZCByZWdpb24/CgpgYGB7cn0KCmZpdCA9IGh5cG90aGVzaXMoYWxsTW9kZWxzW1sndHNwX2FjY18wNF9yX0EnXV0sIm92ZXJDb25zdHJhaW5lZFRSVUU9dW5kZXJDb25zdHJhaW5lZFRSVUUiLCBzZWVkPXNlZWRfYnJtcykKCnByaW50KGZpdCkKCmhkaShmaXQkc2FtcGxlcyxjaT0wLjk1KQoKYGBgCgoqKlJlZ2lvbiBlZmZlY3Qgb24gYWNjdXJhY3kgYnkgcmVnaW9uIGFuZCBzYXRpc2ZpYWJpbGl0eSoqCgpgYGB7ciAsIGZpZy5hbGlnbj0nY2VudGVyJ30KZGF0YUlucHV0PWRhdGFUcmlhbF9UU1AgCgojIGRhdGFJbnB1dCRwSUQ9YXMuY2hhcmFjdGVyKGRhdGFJbnB1dCRwSUQpCiMgcHMgPSBzYW1wbGUocHVsbChkYXRhSW5wdXQscElEKSwyMCkKIyBkYXRhSW5wdXQgPSBkYXRhSW5wdXQgJT4lIGZpbHRlcihwSUQgJWluJSBwcykKCmRhdGFJbnB1dDI9ZGF0YUlucHV0ICU+JSBncm91cF9ieShyZWdpb24scElELHNvbCklPiVzdW1tYXJpc2UoYWNjdXJhY3kxPW1lYW4oY29ycmVjdCkpJT4ldW5ncm91cCgpJT4lZ3JvdXBfYnkocmVnaW9uLHNvbCklPiVzdW1tYXJpc2UoYWNjdXJhY3k9bWVhbihhY2N1cmFjeTEpLHNlPXNlKGFjY3VyYWN5MSkpJT4ldW5ncm91cCgpCgpkYXRhSW5wdXQyJHJlZ2lvbiA8LSBmYWN0b3IoZGF0YUlucHV0MiRyZWdpb24sIGxldmVscyA9IGMoJ1VuZGVyY29uc3RyYWluZWQnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1BoYXNlIFRyYW5zaXRpb24nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ092ZXJjb25zdHJhaW5lZCcpKQoKZGF0YUlucHV0MiRzb2wgPSByZWNvZGUoZGF0YUlucHV0MiRzb2wsICcxJyA9ICJTb2x2YWJsZSIsICcwJyA9ICJOb24tU29sdmFibGUiKQoKcGxvPSBnZ3Bsb3QoZGF0YT1kYXRhSW5wdXQyLCBhZXMoeT1hY2N1cmFjeSwgeD1yZWdpb24sIGxhYmVsID0gcm91bmQoYWNjdXJhY3ksZGlnaXRzID0gMikpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49YWNjdXJhY3ktc2UsIHltYXg9YWNjdXJhY3krc2UpLCB3aWR0aD0uMSkrCiAgbGFicyh0aXRsZT0iQWNjdXJhY3kgYnkgcmVnaW9uIix4PSJSZWdpb24iLHk9IkFjY3VyYWN5IikrCiAgY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDAuNSwxKSkrCiAgZ2VvbV90ZXh0KGhqdXN0PTAuNSx2anVzdCA9IDUsIGNvbG91cj0id2hpdGUiKSArCiAgdGhlbWVfbGlnaHQoKSsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCAKICAgICAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSsKICBmYWNldF9ncmlkKC5+c29sKQoKCm91dHB1dE5hbWUgPSAndHNwX2FjY18wNV9nJwpwbG90RXhwb3J0KHBsbyxvdXRwdXROYW1lLGZvbGRlck91dF9maWd1cmVzKQoKI1N0YXRzIHRlc3QgZm9yIHRpbWUgaW4gYW5kIG91dCBvZiBwaGFzZSB0cmFuc2l0aW9uOiBBTk9WQQpkYXRhSW5wdXQkb3ZlckNvbnN0cmFpbmVkPSAoZGF0YUlucHV0JHJlZ2lvbj09J092ZXJjb25zdHJhaW5lZCcpCmRhdGFJbnB1dCR1bmRlckNvbnN0cmFpbmVkPSAoZGF0YUlucHV0JHJlZ2lvbj09J1VuZGVyY29uc3RyYWluZWQnKQoKYGBgCgojIyMgTnVtYmVyIG9mIHNvbHV0aW9uIHdpdG5lc3NlcyB7I3RzcF9hY2NfbnNvbH0KCkRpZmZlcmVuY2UgaW4gdGhlIG51bWJlciBvZiB3aXRuZXNzZXMgZm9yIGluc3RhbmNlcyB3aXRoIGxvdy9oaWdoIFRDQwoKYGBge3J9CiNOdW1iZXIgb2Ygc29sdXRpb25zIG9mIHNvbHZhYmxlIHNvbHV0aW9uczogTWVhbiBkaWZmZXJlbmNlIGJldHdlZW4gbG93L2hpZ2ggVENDCgpkYXRhSW5wdXQyID0gdW5pcXVlKGRhdGFJbnB1dCAlPiUgc2VsZWN0KHBoYXNlVCxpZCxuU29sdXRpb25zLHNvbCkgJT4lIGZpbHRlcihzb2w9PTEpKQpkaWZmTWVhbnMgPSB0LnRlc3QoblNvbHV0aW9ucyB+IHBoYXNlVCAsZGF0YT1kYXRhSW5wdXQyKQpwYW5kZXIoZGlmZk1lYW5zKQpgYGAKCmBgYHtyLCBmaWcuYWxpZ249J2NlbnRlcid9CmRhdGFJbnB1dD1kYXRhVHJpYWxfVFNQCgojUGxvdHMgblNvbHV0aW9ucyAoeCkgdnMuIEFjY3VyYWN5ICh5KQpkYXRhSW5wdXQzID0gZGF0YUlucHV0ICU+JSBncm91cF9ieShuU29sdXRpb25zLHBJRCxwaGFzZVQpJT4lc3VtbWFyaXNlKGFjY3VyYWN5TWVhbnM9bWVhbihjb3JyZWN0KSklPiV1bmdyb3VwKCklPiVncm91cF9ieShuU29sdXRpb25zLHBoYXNlVCklPiVzdW1tYXJpc2UoYWNjdXJhY3k9bWVhbihhY2N1cmFjeU1lYW5zKSxzZT1zZShhY2N1cmFjeU1lYW5zKSklPiV1bmdyb3VwKCkKCmRhdGFJbnB1dDMkc29sID0gYXMuZmFjdG9yKGRhdGFJbnB1dDMkblNvbHV0aW9ucz49MSkKZGF0YUlucHV0MyRwaGFzZVQgPSByZWNvZGUoZGF0YUlucHV0MyRwaGFzZVQsICcwJyA9ICJMb3cgSUMiLCAnMScgPSAiSGlnaCBJQyIpCmRhdGFJbnB1dDMkblNvbHV0aW9ucz1kYXRhSW5wdXQzJG5Tb2x1dGlvbnMrMQogIApwbG89ICBnZ3Bsb3QoZGF0YT1kYXRhSW5wdXQzLCBhZXMoeT1hY2N1cmFjeSwgeD1uU29sdXRpb25zKSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49YWNjdXJhY3ktc2UsIHltYXg9YWNjdXJhY3krc2UpLCB3aWR0aD0uMSkrCiAgZ2VvbV9wb2ludChzaGFwZT0yMywgc2l6ZT0zLCBmaWxsPSJyZWQiKSsKICBsYWJzKHRpdGxlPSJBY2N1cmFjeSBhbmQgdGhlIE51bWJlciBvZiBTb2x1dGlvbnMiLAogICAgICAgeD0ibG9nKE51bWJlciBvZiBTb2x1dGlvbnMpIix5PSJBY2N1cmFjeSIpKwogIGNvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLjMsMSkpKwogIHRoZW1lX2xpZ2h0KCkrCiAgc2NhbGVfeF9sb2cxMCgpKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksc3RyaXAudGV4dC54ID0gZWxlbWVudF9ibGFuaygpKSsKICBmYWNldF9ncmlkKHBoYXNlVH5zb2wsIHNjYWxlcyA9ICJmcmVlX3giLCBzcGFjZSA9ICJmcmVlX3giKSsKICBnZW9tX3Ntb290aChkYXRhPWRhdGFJbnB1dDMsIGFlcyh5PWFjY3VyYWN5LCB4PW5Tb2x1dGlvbnMpLG1ldGhvZD1nbG0sc2U9RkFMU0UsZnVsbHJhbmdlPVRSVUUsbGluZXR5cGUgPSAiZGFzaGVkIikKCgpvdXRwdXROYW1lID0gJ3RzcF9uc29sX2FjY19nJwpwbG90RXhwb3J0KHBsbyxvdXRwdXROYW1lLGZvbGRlck91dF9maWd1cmVzKQpgYGAKCgpgYGB7cn0KZGF0YUlucHV0PWRhdGFUcmlhbF9UU1AKCmRhdGFJbnB1dCA9IGRhdGFJbnB1dCAlPiUgZmlsdGVyKHNvbD09MSkKCmRhdGFJbnB1dCRuU29sdXRpb25zX2xvZyA9bG9nKGRhdGFJbnB1dCRuU29sdXRpb25zKQpsb2dpdFJhbmRvbUludGVyY2VwdCA9IGJybTIoY29ycmVjdCB+IG5Tb2x1dGlvbnNfbG9nICsgcGhhc2VUICsgcGhhc2VUOm5Tb2x1dGlvbnNfbG9nICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5PWJlcm5vdWxsaShsaW5rPSJsb2dpdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoID0gMCkKCnRhYmxlTmFtZT0ndHNwX2FjY19uczEnCnNhdmVfc3VtbWFyaXNlX21vZGVsKGxvZ2l0UmFuZG9tSW50ZXJjZXB0LCB0YWJsZU5hbWUpCmBgYAoKVGhpcyBjYWxjdWxhdGVzIHRoZSBzaWduaWZpY2FuY2Ugb2YgdGhlICBwLXZhbHVlIG9mIHRoZSBiZXRhKHNsb3BlKSBvZiBudW1iZXIgb2Ygd2l0bmVzc2VzIGZvciBpbnN0YW5jZXMgd2l0aCBoaWdoIFRDQy4KCmBgYHtyfQpmaXQgPSBoeXBvdGhlc2lzKGFsbE1vZGVsc1tbJ3RzcF9hY2NfbnMxJ11dLCJuU29sdXRpb25zX2xvZyArIG5Tb2x1dGlvbnNfbG9nOnBoYXNlVCA9IDAiLCBzZWVkPXNlZWRfYnJtcykKCnByaW50KGZpdCkKCmhkaShmaXQkc2FtcGxlcyxjaT0wLjk1KQpgYGAKCk1hcmdpbmFsIEVmZmVjdHMKCmBgYHtyfQpwbG90KG1hcmdpbmFsX2VmZmVjdHMoYWxsTW9kZWxzW1sndHNwX2FjY19uczEnXV0pLCBwbG90ID0gVFJVRSwgYXNrID0gRkFMU0UpCgpgYGAKCiMjIyMgTlNvbCAocmVncmVzc2VkIGFsb25lKQoKYGBge3J9CiNzdDAyCmRhdGFJbnB1dD1kYXRhVHJpYWxfVFNQCmRhdGFJbnB1dCA9IGRhdGFJbnB1dCAlPiUgZmlsdGVyKHNvbD09MSkKZGF0YUlucHV0JG5Tb2x1dGlvbnNfbG9nID1sb2coZGF0YUlucHV0JG5Tb2x1dGlvbnMpCgojSW5jbHVkZXMgYSBkdW1teSBpZiBuU29sdXRpb25zPT0wLCB0aGF0J3MgdmFyaWFibGU6IHNvbC4KbG9naXRSYW5kb21JbnRlcmNlcHQgPSBicm0yKGNvcnJlY3QgfiBuU29sdXRpb25zX2xvZyArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseT1iZXJub3VsbGkobGluaz0ibG9naXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwKQoKdGFibGVOYW1lPSd0c3BfYWNjX25zMicKc2F2ZV9zdW1tYXJpc2VfbW9kZWwobG9naXRSYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKYGBgCgpgYGB7cn0KbWVhbl9hY2MgPSBkYXRhSW5wdXQgJT4lIGdyb3VwX2J5KGluc3RhbmNlTnVtYmVyLG5Tb2x1dGlvbnNfbG9nLCBzb2wscGhhc2VUKSAlPiUKICBzdW1tYXJpc2UoYWNjdXJhY3k9bWVhbihjb3JyZWN0KSkgCgpsb2dpdFJhbmRvbUludGVyY2VwdCA9IGFsbE1vZGVsc1tbJ3RzcF9hY2NfbnMyJ11dCnBwICA9IHBsb3QoY29uZGl0aW9uYWxfZWZmZWN0cyhsb2dpdFJhbmRvbUludGVyY2VwdCksIHBsb3QgPSBGQUxTRSwgYXNrID0gRkFMU0UpCgpwcCRuU29sdXRpb25zX2xvZyArIAogIGdlb21fcG9pbnQoZGF0YT1tZWFuX2FjYyxhZXMoeCA9IG5Tb2x1dGlvbnNfbG9nLCB5ID0gYWNjdXJhY3kpLGluaGVyaXQuYWVzID0gRkFMU0UpCgpgYGAKCmBgYHtyfQojIEltcHJvdmluZyB0aGUgcGxvdApzaXplX2JpZyA9IDIwCnNpemVfc21hbGwgPSAxNgpzaXplX3NzID0gMTAKc2l6ZV94cyA9IDcKCnBwX3Bsb3QgPSBwcCRuU29sdXRpb25zX2xvZwpwcF9wbG90JGxheWVyc1tbMV1dJGdlb21fcGFyYW1zJHNlID0gRkFMU0UKcHBfcGxvdCRsYXllcnNbWzFdXSRhZXNfcGFyYW1zJGNvbG91cj0iIzU3NzU5MCIKCnBwX3Bsb3QkbGF5ZXJzIDwtIGMoZ2VvbV9wb2ludChkYXRhPW1lYW5fYWNjLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBuU29sdXRpb25zX2xvZywgeSA9IGFjY3VyYWN5LCBjb2w9YXMuZmFjdG9yKHNvbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcGU9YXMuZmFjdG9yKHBoYXNlVCksIHNpemU9Mi41KSwgaW5oZXJpdC5hZXMgPSBGQUxTRSksCiAgICAgICAgICAgICAgICAgICAgICAgICBwcF9wbG90JGxheWVycykKCgpwbG8gPSBwcF9wbG90ICsKICB4bGFiKCJOdW1iZXIgb2Ygc29sdXRpb24gV2l0bmVzc2VzIChsbikiKSsjZXhwcmVzc2lvbihJQ1tleHBvc3RdKSkrCiAgeWxhYigiSHVtYW4gUGVyZm9ybWFuY2UiKSsKICBzY2FsZV9zaGFwZV9tYW51YWwobmFtZT0iIix2YWx1ZXMgPSBjKDE3LDE2KSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbChuYW1lPSIiLHZhbHVlcyA9IGMoIjEiPSIjOTBCRTZEIiwiMCI9IiNGOTQxNDQiKSkrCiAgdGhlbWVfY2xhc3NpYygpKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0gc2l6ZV9iaWcpLAogICAgICAgYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPXNpemVfc21hbGwpLAogICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYyhsb2coMSksbG9nKDEwKSxsb2coMTAwKSxsb2coMTAwMCksbG9nKDEwMDAwKSksCiAgICAgICAgICAgICAgICAgICAgIGxpbWl0cyA9YygwLE5BKSxsYWJlbHMgPSBjKCIxIiwiMTAiLCIxMDAiLCIxMDAwIiwiMTAwMDAiKSApKwogIGd1aWRlcyhzaGFwZSA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzKSkpKwogIHlsaW0oMC4yLDEpCgoKcGxvCmdnc2F2ZShwYXN0ZTAoZm9sZGVyT3V0X2ZpZ3VyZXMsIi9Od2l0X1RTUF9hY2MucGRmIikscGxvLHdpZHRoID0gNixoZWlnaHQgPTYsdW5pdHM9ImluIikKYGBgCgojIyMjIE5Tb2wgKHdpdGggVENDIGFuZCBubyBpbnRlcmFjdGlvbikKCmBgYHtyfQojc3QwMwpkYXRhSW5wdXQ9ZGF0YVRyaWFsX1RTUApkYXRhSW5wdXQgPSBkYXRhSW5wdXQgJT4lIGZpbHRlcihzb2w9PTEpCmRhdGFJbnB1dCRuU29sdXRpb25zX2xvZyA9bG9nKGRhdGFJbnB1dCRuU29sdXRpb25zKQoKCmxvZ2l0UmFuZG9tSW50ZXJjZXB0ID0gYnJtMihjb3JyZWN0IH4gblNvbHV0aW9uc19sb2cgKyBwaGFzZVQgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBmYW1pbHk9YmVybm91bGxpKGxpbms9ImxvZ2l0IiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCkKCnRhYmxlTmFtZT0ndHNwX2FjY19uczMnCnNhdmVfc3VtbWFyaXNlX21vZGVsKGxvZ2l0UmFuZG9tSW50ZXJjZXB0LCB0YWJsZU5hbWUpCmBgYAoKIyMjIElDX2V4cG9zdCB7I3RzcF9hY2NfSUNleHBvc3R9CgpgYGB7ciwgZmlnLmFsaWduPSdjZW50ZXInfQpkYXRhSW5wdXQgPSBkYXRhVHJpYWxfVFNQCgojIFN1bW1hcmlzZSB0aGUgZGF0YSB0byBwbG90Cm1lYW5fYWNjdXJhY3kgPSBkYXRhSW5wdXQgJT4lIAogIGdyb3VwX2J5KGluc3RhbmNlTnVtYmVyLCBzb2wsIElDZXhwb3N0LCBwaGFzZVQsIG5Tb2x1dGlvbnMpICU+JSAKICBzdW1tYXJpc2UoYWNjdXJhY3kgPSBtZWFuKGNvcnJlY3QpKQoKZ2dwbG90KG1lYW5fYWNjdXJhY3ksYWVzKHggPSBJQ2V4cG9zdCwgeSA9IGFjY3VyYWN5KSkrCiAgZ2VvbV9wb2ludCgpICsKICB0aGVtZV9saWdodCgpICsKICBzdGF0X3Ntb290aChmb3JtdWxhID0gIHkgfiBJKHheMC4wMSksIG1ldGhvZD0ibG0iLCBzZT0gRkFMU0UpKwogIHhsYWIoIklDX2V4cG9zdCIpKwogIHlsYWIoIkh1bWFuIEFjY3VyYWN5IikKCmBgYAoKIyMjIyBBbGwgaW5zdGFuY2VzCgpgYGB7cn0KbW9kZWxfSUNleHBvc3QgPSBicm0yKGNvcnJlY3QgfiBJQ2V4cG9zdCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseT1iZXJub3VsbGkobGluaz0ibG9naXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaCA9IDApCgp0YWJsZU5hbWU9J3RzcF9hY2NfaWNleHBvc3QnCnNhdmVfc3VtbWFyaXNlX21vZGVsKG1vZGVsX0lDZXhwb3N0LCB0YWJsZU5hbWUpCgpgYGAKCmBgYHtyfQoKbW9kZWxfSUNleHBvc3QgPSBhbGxNb2RlbHNbWyd0c3BfYWNjX2ljZXhwb3N0J11dCnBwICA9IHBsb3QoY29uZGl0aW9uYWxfZWZmZWN0cyhtb2RlbF9JQ2V4cG9zdCksIHBsb3QgPSBUUlVFLCBhc2sgPSBGQUxTRSkKCm1lYW5fYWNjdXJhY3kkY29ycmVjdD0gbWVhbl9hY2N1cmFjeSRhY2N1cmFjeQpwcCRJQ2V4cG9zdCArIAogIGdlb21fcG9pbnQoZGF0YT1tZWFuX2FjY3VyYWN5LGFlcyh4ID0gSUNleHBvc3QsIHkgPSBjb3JyZWN0LCBjb2w9YXMuZmFjdG9yKHBoYXNlVCkpLGluaGVyaXQuYWVzID0gRkFMU0UpKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCmBgYHtyfQojIEltcHJvdmluZyB0aGUgcGxvdApzaXplX2JpZyA9IDIwCnNpemVfc21hbGwgPSAxNgpzaXplX3NzID0gMTAKc2l6ZV94cyA9IDcKCnBwX3Bsb3QgPSBwcCRJQ2V4cG9zdApwcF9wbG90JGxheWVyc1tbMV1dJGdlb21fcGFyYW1zJHNlID0gRkFMU0UKcHBfcGxvdCRsYXllcnNbWzFdXSRhZXNfcGFyYW1zJGNvbG91cj0iIzU3NzU5MCIKCnBwX3Bsb3QkbGF5ZXJzIDwtIGMoZ2VvbV9wb2ludChkYXRhPW1lYW5fYWNjdXJhY3ksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IElDZXhwb3N0LCB5ID0gY29ycmVjdCwgY29sPWFzLmZhY3Rvcihzb2wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpLCBzaXplPTIuNSksIGluaGVyaXQuYWVzID0gRkFMU0UpLAogICAgICAgICAgICAgICAgICAgICAgICAgcHBfcGxvdCRsYXllcnMpCgoKcGxvID0gcHBfcGxvdCArCiAgeGxhYigiSW5zdGFuY2UgQ29tcGxleGl0eSAoSUMpIikrI2V4cHJlc3Npb24oSUNbZXhwb3N0XSkpKwogIHlsYWIoIkh1bWFuIFBlcmZvcm1hbmNlIikrCiAgc2NhbGVfc2hhcGVfbWFudWFsKG5hbWU9IiIsdmFsdWVzID0gYygxNywxNikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwobmFtZT0iIix2YWx1ZXMgPSBjKCIxIj0iIzkwQkU2RCIsIjAiPSIjRjk0MTQ0IikpKwogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMpKSkrCiAgeWxpbSgwLjIsMSkKCnBsbwpnZ3NhdmUocGFzdGUwKGZvbGRlck91dF9maWd1cmVzLCIvSUNfVFNQX2FjYy5wZGYiKSxwbG8sd2lkdGggPSA2LGhlaWdodCA9Nix1bml0cz0iaW4iKQpgYGAKCiMjIyMjIE1vZGVsIEZpdAoKYGBge3J9CiNzdDA1CmRhdGFJbnB1dCA9IGRhdGFUcmlhbF9UU1AKCiMgTWFrZSBwcmVkaWN0aW9ucyBleGNsdWRpbmcgcmFuZG9tIGVmZmVjdHMgKHBJRCkKcHJlZGljdGlvbnMgPSBwcmVkaWN0KG1vZGVsX0lDZXhwb3N0LGRhdGFJbnB1dCwgcmVfZm9ybXVsYSA9IE5BKQoKCiMgRXN0aW1hdGluZyB0aGUgc2lnbmlmaWNhbmNlIG9mIHRoZSBmaXQuIFRoaXMgaXMgZG9uZSBjb25zaWRlcmluZyB0aGUgcHJvYmFiaWxpdHkgZXN0aW1hdGlvbiByYXRoZXIgdGhhbiB0aGUgYmluYXJ5IGNsYXNzaWZpY2F0aW9uLgoKI1BlcmZvcm1zIHRoZSBIb3NtZXItTGVtZXNob3cgZ29vZG5lc3Mgb2YgZml0IHRlc3QKbG9naXN0aWNfc2lnbmlmaWNhbmNlID0gZ2VuZXJhbGhvc2xlbTo6bG9naXRnb2YoZGF0YUlucHV0JGNvcnJlY3QsIHByZWRpY3Rpb25zWywxXSwgZyA9IDEwLCBvcmQgPSBGQUxTRSkKbG9naXN0aWNfc2lnbmlmaWNhbmNlCgojIEZpbmRzIFIyIHVzaW5nIGJpbmFyeSBvdXRjb21lcwojIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzQwOTAxNDQ1L2Z1bmN0aW9uLXRvLWNhbGN1bGF0ZS1yMi1yLXNxdWFyZWQtaW4tcgojcHJlZGljdGlvbnMgPSBwcmVkaWN0KG1vZGVsX0lDZXhwb3N0LGRhdGFJbnB1dCwgcmVfZm9ybXVsYSA9IE5BKQpyXzJfYmluYXJ5ID0gY29yKGRhdGFJbnB1dCRjb3JyZWN0LCBwcmVkaWN0aW9uc1ssMV0pXjIKcl8yX2JpbmFyeQoKIyBGaW5kcyBSMiB1c2luZyBtZWFuIGFjY3VyYWNpZXMgcGVyIGluc3RhbmNlCnByZWRpY3Rpb25zMiA9IHByZWRpY3QobW9kZWxfSUNleHBvc3QsbWVhbl9hY2N1cmFjeSwgcmVfZm9ybXVsYSA9IE5BKQpyXzJfcHJvYmFiaWxpdGllcyA9IGNvcihtZWFuX2FjY3VyYWN5JGFjY3VyYWN5LCBwcmVkaWN0aW9uczJbLDFdKV4yCnJfMl9wcm9iYWJpbGl0aWVzCmBgYAoKIyMjIyBVbnNhdGlzZmlhYmxlIGluc3RhbmNlcwoKYGBge3J9CmRhdGFJbnB1dCA9IGRhdGFUcmlhbF9UU1AKZGF0YUlucHV0ID0gZGF0YUlucHV0ICU+JSBmaWx0ZXIoc29sPT0wKQptb2RlbF9JQ2V4cG9zdCA9IGJybTIoY29ycmVjdCB+IElDZXhwb3N0ICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZmFtaWx5PWJlcm5vdWxsaShsaW5rPSJsb2dpdCIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgICByZWZyZXNoID0gMCkKCnRhYmxlTmFtZT0ndHNwX2FjY19pY2V4cG9zdDInCnNhdmVfc3VtbWFyaXNlX21vZGVsKG1vZGVsX0lDZXhwb3N0LCB0YWJsZU5hbWUpCgpgYGAKCmBgYHtyfQojc3QwNQpkYXRhSW5wdXQgPSBkYXRhVHJpYWxfVFNQICU+JSBmaWx0ZXIoc29sPT0wKQoKbW9kZWxfSUNleHBvc3QgPSBhbGxNb2RlbHNbWyd0c3BfYWNjX2ljZXhwb3N0MiddXQojIE1ha2UgcHJlZGljdGlvbnMgZXhjbHVkaW5nIHJhbmRvbSBlZmZlY3RzIChwSUQpCnByZWRpY3Rpb25zID0gcHJlZGljdChtb2RlbF9JQ2V4cG9zdCxkYXRhSW5wdXQsIHJlX2Zvcm11bGEgPSBOQSkKCiMgRXN0aW1hdGluZyB0aGUgc2lnbmlmaWNhbmNlIG9mIHRoZSBmaXQuIFRoaXMgaXMgZG9uZSBjb25zaWRlcmluZyB0aGUgcHJvYmFiaWxpdHkgZXN0aW1hdGlvbiByYXRoZXIgdGhhbiB0aGUgYmluYXJ5IGNsYXNzaWZpY2F0aW9uLgoKI1BlcmZvcm1zIHRoZSBIb3NtZXItTGVtZXNob3cgZ29vZG5lc3Mgb2YgZml0IHRlc3QKbG9naXN0aWNfc2lnbmlmaWNhbmNlID0gZ2VuZXJhbGhvc2xlbTo6bG9naXRnb2YoZGF0YUlucHV0JGNvcnJlY3QsIHByZWRpY3Rpb25zWywxXSwgZyA9IDEwLCBvcmQgPSBGQUxTRSkKbG9naXN0aWNfc2lnbmlmaWNhbmNlCgojIEZpbmRzIFIyIHVzaW5nIGJpbmFyeSBvdXRjb21lcwojIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzQwOTAxNDQ1L2Z1bmN0aW9uLXRvLWNhbGN1bGF0ZS1yMi1yLXNxdWFyZWQtaW4tcgojcHJlZGljdGlvbnMgPSBwcmVkaWN0KG1vZGVsX0lDZXhwb3N0LGRhdGFJbnB1dCwgcmVfZm9ybXVsYSA9IE5BKQpyXzJfYmluYXJ5ID0gY29yKGRhdGFJbnB1dCRjb3JyZWN0LCBwcmVkaWN0aW9uc1ssMV0pXjIKcl8yX2JpbmFyeQoKIyBGaW5kcyBSMiB1c2luZyBtZWFuIGFjY3VyYWNpZXMgcGVyIGluc3RhbmNlCgptZWFuX2FjY3VyYWN5X3Vuc2F0ID0gbWVhbl9hY2N1cmFjeSAlPiUgZmlsdGVyKHNvbD09MCkKcHJlZGljdGlvbnMyID0gcHJlZGljdChtb2RlbF9JQ2V4cG9zdCxtZWFuX2FjY3VyYWN5X3Vuc2F0LCByZV9mb3JtdWxhID0gTkEpCnJfMl9wcm9iYWJpbGl0aWVzID0gY29yKG1lYW5fYWNjdXJhY3lfdW5zYXQkYWNjdXJhY3ksIHByZWRpY3Rpb25zMlssMV0pXjIKcl8yX3Byb2JhYmlsaXRpZXMKYGBgCgojIyBUaW1lIFNwZW50CgpUaGUgZGVmYXVsdCBkYXRhIHVzZWQgaW4gdGhpcyBzZWN0aW9uIGlzIGBkYXRhVHJpYWxfVFNQX1RpbWVgLiBUaGlzIGRhdGFzZXQgZXhjbHVkZXMgdGhvc2UgcGFydGljaXBhbnRzIHRoYXQgbmV2ZXIgc2tpcHBlZCB0byBhbnN3ZXIKc3VibWlzc2lvbi4KCldlIGZpcnN0IGNhbGN1bGF0ZSBzb21lIHN1bW1hcnkgc3RhdHMgZm9yIHRoZSB3aG9sZSBkYXRhIHNldCAoYGRhdGFUcmlhbF9UU1BgKSBhbmQgc2VlIGhvdyBtYW55IHBhcnRpY2lwYW50cyB3ZXJlIGV4Y2x1ZGVkIGluIGBkYXRhVHJpYWxfVFNQX1RpbWVgLgoKIyMjIyBTdW1tU3RhdHMgYFRTUGAKCmBgYHtyLCByZXN1bHRzPSdhc2lzJ30KI1N1bW1hcnkgU3RhdHMgZm9yIERlY2lzaW9uIFByb2JsZW0KZGF0YUlucHV0PWRhdGFUcmlhbF9UU1AKCnRpbWVTdW1tYXJ5ID0gZGF0YUlucHV0ICU+JSBncm91cF9ieShwSUQpICU+JSBzdW1tYXJpc2UoYWNjPW1lYW4odGltZVNwZW50KSkgJT4lIHN1bW1hcmlzZShtZWFuPW1lYW4oYWNjKSxtaW49bWluKGFjYyksbWF4PW1heChhY2MpLFNEPXNkKGFjYykpCmthYmxlKHRpbWVTdW1tYXJ5LCBkaWdpdHM9MSwgY2FwdGlvbiA9ICJUaW1lIFN1bW1hcnkiKQoKeWVzTm9Qcm9wb3J0aW9ucyA9IGRhdGFJbnB1dCAlPiUgZ3JvdXBfYnkoc29sLHBJRCkgJT4lIHN1bW1hcmlzZShhY2M9bWVhbih0aW1lU3BlbnQpKSAlPiUgc3VtbWFyaXNlKG1lYW49bWVhbihhY2MpLG1pbj1taW4oYWNjKSxtYXg9bWF4KGFjYyksU0Q9c2QoYWNjKSkKa2FibGUoeWVzTm9Qcm9wb3J0aW9ucywgZGlnaXRzPTEsIGNhcHRpb24gPSAiVGltZSBTcGVudCBCeSBTb2x1dGlvbiIpCgpoaXN0KGRhdGFJbnB1dCR0aW1lU3BlbnQsYnJlYWtzPTQwKQoKYGBgCgpgYGB7cn0KYWxsX3BJRHMgPSB1bmlxdWUoZGF0YVRyaWFsX1RTUCRwSUQpCnBJRHNfbm90X2luX1RpbWUgPSBhbGxfcElEc1shKGFsbF9wSURzICVpbiUgdW5pcXVlKGRhdGFUcmlhbF9UU1BfVGltZSRwSUQpKV0KcHJpbnQocGFzdGUwKCJUaGUgcGFydGljaXBhbnRzIHJlbW92ZWQgaW4gdGhlIFRJTUUgZGYgYXJlICIsIGxlbmd0aChwSURzX25vdF9pbl9UaW1lKSkpCgoKCm9ic19yZW1vdmVkID0gbnJvdyhkYXRhVHJpYWxfVFNQKS1ucm93KGRhdGFUcmlhbF9UU1BfVGltZSkKcHJpbnQocGFzdGUwKCJUaGUgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyByZW1vdmVkIGluIHRoZSBUSU1FIGRmIGlzICIsIG9ic19yZW1vdmVkKSkKCmBgYAoKIyMjIyBTdW1tU3RhdHMgYFRTUF9UaW1lYAoKYGBge3IsIHJlc3VsdHM9J2FzaXMnfQojU3VtbWFyeSBTdGF0cyBmb3IgRGVjaXNpb24gUHJvYmxlbQpkYXRhSW5wdXQ9ZGF0YVRyaWFsX1RTUF9UaW1lCgp0aW1lU3VtbWFyeSA9IGRhdGFJbnB1dCAlPiUgZ3JvdXBfYnkocElEKSAlPiUgc3VtbWFyaXNlKGFjYz1tZWFuKHRpbWVTcGVudCkpICU+JSBzdW1tYXJpc2UobWVhbj1tZWFuKGFjYyksbWluPW1pbihhY2MpLG1heD1tYXgoYWNjKSxTRD1zZChhY2MpKQprYWJsZSh0aW1lU3VtbWFyeSwgZGlnaXRzPTEsIGNhcHRpb24gPSAiVGltZSBTdW1tYXJ5IikKCnllc05vUHJvcG9ydGlvbnMgPSBkYXRhSW5wdXQgJT4lIGdyb3VwX2J5KHNvbCxwSUQpICU+JSBzdW1tYXJpc2UoYWNjPW1lYW4odGltZVNwZW50KSkgJT4lIHN1bW1hcmlzZShtZWFuPW1lYW4oYWNjKSxtaW49bWluKGFjYyksbWF4PW1heChhY2MpLFNEPXNkKGFjYykpCmthYmxlKHllc05vUHJvcG9ydGlvbnMsIGRpZ2l0cz0xLCBjYXB0aW9uID0gIlRpbWUgU3BlbnQgQnkgU29sdXRpb24iKQoKaGlzdChkYXRhSW5wdXQkdGltZVNwZW50LGJyZWFrcz00MCkKCmBgYAoKIyMjIyBUcmlhbCBOdW1iZXIgYW5kIFRpbWUgU3BlbnQKCmBgYHtyfQojVHJpYWwgKGV4cGVyaWVuY2UgZWZmZWN0KSBlZmZlY3Qgb24gdGltZVNwZW50CmRhdGFJbnB1dD1kYXRhVHJpYWxfVFNQX1RpbWUKZGF0YUlucHV0JHRvdGFsVHJpYWwgPSBkYXRhSW5wdXQkYmxvY2sgKiBkYXRhSW5wdXQkdHJpYWwKCnN1bW1hcnlCeUJsb2NrID0gZGF0YUlucHV0ICU+JSBncm91cF9ieShibG9jayxwSUQpICU+JSBzdW1tYXJpc2UodGltZT1tZWFuKHRpbWVTcGVudCkpICU+JSBzdW1tYXJpc2UobWVhbj1tZWFuKHRpbWUpLG1pbj1taW4odGltZSksbWF4PW1heCh0aW1lKSxTRD1zZCh0aW1lKSkKa2FibGUoc3VtbWFyeUJ5QmxvY2ssZGlnaXRzPTIgLCBjYXB0aW9uPSJUaW1lIFNwZW50IHBlciBUcmlhbCBzZWdyZWdhdGVkIEJ5IEJsb2NrIikKCiNSZWdyZXNzaW9uCmxpbmVhclJhbmRvbUludGVyY2VwdCA9IGJybTIodGltZVNwZW50X3BjdCB8IGNlbnMoY2Vuc29yZWRfdGltZSkgfiB0b3RhbFRyaWFsKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwLCBpdGVyID0gaXRlcnNfaGlnaCkKCgp0YWJsZU5hbWU9J3RzcF90aW1lXzAxX3InCnNhdmVfc3VtbWFyaXNlX21vZGVsKGxpbmVhclJhbmRvbUludGVyY2VwdCwgdGFibGVOYW1lKQpgYGAKCiMjIyBUQ0MKCmBgYHtyICwgZmlnLmFsaWduPSdjZW50ZXInfQpkYXRhSW5wdXQ9ZGF0YVRyaWFsX1RTUF9UaW1lICU+JSBncm91cF9ieShwaGFzZVQscElEKSU+JXN1bW1hcmlzZSh0aW1lU3BlbnQxPW1lYW4odGltZVNwZW50KSklPiUKICB1bmdyb3VwKCklPiVncm91cF9ieShwaGFzZVQpJT4lc3VtbWFyaXNlKHRpbWVTcGVudD1tZWFuKHRpbWVTcGVudDEpLHNlPXNlKHRpbWVTcGVudDEpKSU+JXVuZ3JvdXAoKQoKZGF0YUlucHV0JHBoYXNlVCA9IHJlY29kZShkYXRhSW5wdXQkcGhhc2VULCAnMCcgPSAiTG93IElDIiwgJzEnID0gIkhpZ2ggSUMiKQoKcGxvPSBnZ3Bsb3QoZGF0YT1kYXRhSW5wdXQsIGFlcyh5PXRpbWVTcGVudCwgeD1hcy5mYWN0b3IocGhhc2VUKSxsYWJlbCA9IHJvdW5kKHRpbWVTcGVudCxkaWdpdHMgPSAxKSkpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikrCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj10aW1lU3BlbnQtc2UsIHltYXg9dGltZVNwZW50K3NlKSwgd2lkdGg9LjEpKwogICNnZW9tX3NpZ25pZihjb21wYXJpc29ucyA9IGxpc3QoYygiTG93IElDIiwiSGlnaCBJQyIpKSwgYW5ub3RhdGlvbnM9IioqKiIsIHlfcG9zaXRpb24gPSAwLjk1LCB0aXBfbGVuZ3RoID0gMC4wMykrCiAgbGFicyh0aXRsZT0iVGltZSBTcGVudCBJbiBhbmQgT3V0IG9mIHBoYXNlIFRyYW5zaXRpb24iLHg9Ikluc3RhbmNlIGNvbXBsZXhpdHkiLHk9IlRpbWUgU3BlbnQiKSsKICAjY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDAuNSwxKSkrCiAgZ2VvbV90ZXh0KGhqdXN0PTAuNSx2anVzdCA9IDUsIGNvbG91cj0id2hpdGUiKSsKICB0aGVtZV9saWdodCgpKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCkscGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpCgpvdXRwdXROYW1lID0gInRzcF90aW1lXzAyX2ciCnBsb3RFeHBvcnQocGxvLG91dHB1dE5hbWUsZm9sZGVyT3V0X2ZpZ3VyZXMpCgpgYGAKCmBgYHtyLCByZXN1bHRzPSdhc2lzJ30KI0Fub3ZhIGNvbnRyYXN0IGZvciBJbi9PdXQgUGhhc2UgdHJhbnNpdGlvbgpkYXRhSW5wdXQgPSBkYXRhVHJpYWxfVFNQX1RpbWUKYW5vdmFNb2RlbD1hb3YodGltZVNwZW50fnBoYXNlVCtFcnJvcihwSUQvcGhhc2VUKSxkYXRhSW5wdXQpCmFub3ZhUFZhbHVlPXN1bW1hcnkoYW5vdmFNb2RlbClbWzJdXVtbMV1dW1snUHIoPkYpJ11dW1sxXV0KcHJpbnQocGFzdGUoIlAtdmFsdWUgZm9yIG9uZSB3YXkgQU5PVkE6IixzaWduaWYoYW5vdmFQVmFsdWUsZGlnaXRzPTMpKSkKcm0oZGF0YUlucHV0KQpgYGAKCmB0aW1lU3BlbnQgfiBwaGFzZVQgKyAoMXxwSUQpYAoKYGBge3J9CiNMb2dpc3RpYyBSZWdyZXNzaW9uIGZvciBJbi9PdXQgUGhhc2UgdHJhbnNpdGlvbgpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9UU1BfVGltZQoKI2xvZ2lzdGljIHdpdGggcmFuZG9tIGVmZmVjdHMgKGludGVyY2VwdCkKIyBUVFRPRE8KcmFuZG9tSW50ZXJjZXB0ID0gYnJtMih0aW1lU3BlbnQgfCBjZW5zKGNlbnNvcmVkX3RpbWUpIH4gcGhhc2VUICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwgCiAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywgcmVmcmVzaCA9IDAsIGl0ZXIgPSBpdGVyc19oaWdoKQoKdGFibGVOYW1lPSJ0c3BfdGltZV8wMl9yIgpzYXZlX3N1bW1hcmlzZV9tb2RlbChyYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKCmBgYAoKIyMjIyMgUGxvdCBUQ0MKCmBgYHtyfQpsaWJyYXJ5KGZvcmNhdHMpCmxpYnJhcnkoZ2dwb2wpCiNkYXRhSW5wdXQgPSBkYXRhVHJpYWxfVFNQCgojIGRhdGFJbnB1dCR0aW1lU3BlbnRfcGN0ID0gZGF0YUlucHV0JHRpbWVTcGVudC9TQVRUYXNrTWF4VGltZQojIGRhdGFJbnB1dDIgPSBkYXRhSW5wdXQgJT4lIAojICAgZ3JvdXBfYnkoaW5zdGFuY2VOdW1iZXIscGhhc2VUKSAlPiUgCiMgICBzdW1tYXJpc2UodGltZVNwZW50X3BjdD1tZWRpYW4odGltZVNwZW50X3BjdCkpCgpkYXRhSW5wdXQgPSBkYXRhVHJpYWxfVFNQX1RpbWUgJT4lCiAgbXV0YXRlKHJlZ2lvbiA9IGZjdF9yZWxldmVsKHJlZ2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuZGVyY29uc3RyYWluZWQiLCAiUGhhc2UgVHJhbnNpdGlvbiIsICJPdmVyY29uc3RyYWluZWQiKSkgJT4lIAogIG11dGF0ZShzb2w9IGFzLmZhY3Rvcihzb2wpKSAlPiUgCiAgbXV0YXRlKHNvbCA9IGZjdF9yZWxldmVsKHNvbCwiMSIsICIwIikpCgpkYXRhSW5wdXQkdGltZVNwZW50X3BjdCA9IGRhdGFJbnB1dCR0aW1lU3BlbnQvVFNQVGFza01heFRpbWUKZGF0YUlucHV0MiA9IGRhdGFJbnB1dCAlPiUgCiAgZ3JvdXBfYnkoaW5zdGFuY2VOdW1iZXIscmVnaW9uLHNvbCkgJT4lIAogIHN1bW1hcmlzZSh0aW1lU3BlbnRfcGN0PW1lZGlhbih0aW1lU3BlbnRfcGN0KSkKCmBgYAoKYGBge3J9CnNpemVfYmlnID0gMjAKc2l6ZV9zbWFsbCA9IDE2CnNpemVfc3MgPSAxMApzaXplX3hzID0gNwoKCnBsbyA9IGdncGxvdChkYXRhSW5wdXQyLGFlcyh4PXJlZ2lvbix5PXRpbWVTcGVudF9wY3QsZmlsbD1zb2wpKSsKICAjIGdlb21fYm94aml0dGVyKGFlcyhmaWxsPXJlZ2lvbiksaml0dGVyLmNvbG9yID0gTkEsaml0dGVyLnNoYXBlID0gMjEpKwogIGdlb21fYm94aml0dGVyKGppdHRlci5jb2xvciA9IE5BLGppdHRlci5zaGFwZSA9IDIxLAogICAgICAgICAgICAgICAgIGppdHRlci5wYXJhbXMgPSBsaXN0KGhlaWdodD0wLHNlZWQ9MTApLAogICAgICAgICAgICAgICAgIG91dGxpZXIuc2hhcGU9IE5BKSsKICAgICAgICAgICAgICAgICAjLG91dGxpZXIuc2hhcGUgPSA0LCBvdXRsaWVyLnNpemU9MC45KSsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKSsKICBzY2FsZV9maWxsX21hbnVhbChuYW1lICA9IlJlZ2lvbiIsCiAgICAgICAgICAgICAgICAgICAgYnJlYWtzPWMoIjEiLCIwIiksCiAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIlNhdGlzZmlhYmxlIiwiVW5zYXRpc2ZpYWJsZSIpLAogICAgICAgICAgICAgICAgICAgIHZhbHVlcz1jKCIjOTBCRTZEIiwiI0Y5NDE0NCIpKSsKICB4bGFiKCJUeXBpY2FsIENhc2UgQ29tcGxleGl0eSAoVENDKSIpKwogIHlsYWIoIlRpbWUtb24tdGFzayIpKwogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMpKSkrCiAgeWxpbSgwLjE1LDEpCgpwbG8KZ2dzYXZlKHBhc3RlMChmb2xkZXJPdXRfZmlndXJlcywiL1RDQ19UU1BfdGltZS5wZGYiKSxwbG8sd2lkdGggPSA3LGhlaWdodCA9Nix1bml0cz0iaW4iKQpgYGAKCiMjIyBTYXRpc2ZpYWJpbGl0eSBhbmQgVENDCgpgYGB7ciAsIGZpZy5hbGlnbj0nY2VudGVyJ30KCmRhdGFJbnB1dD1kYXRhVHJpYWxfVFNQX1RpbWUgJT4lIGdyb3VwX2J5KHBoYXNlVCxzb2wscElEKSU+JXN1bW1hcmlzZSh0aW1lU3BlbnQxPW1lYW4odGltZVNwZW50KSklPiV1bmdyb3VwKCklPiVncm91cF9ieShzb2wscGhhc2VUKSU+JXN1bW1hcmlzZSh0aW1lU3BlbnQ9bWVhbih0aW1lU3BlbnQxKSxzZT1zZSh0aW1lU3BlbnQxKSklPiV1bmdyb3VwKCkKCnNvbF9uYW1lcyA8LSBjKAogICAgICAgICAgICAgICAgICAgIGAwYCA9ICJDb3JyZWN0IGFuc3dlcjogTk8iLAogICAgICAgICAgICAgICAgICAgIGAxYCA9ICJDb3JyZWN0IGFuc3dlcjogWUVTIiwKICAgICAgICAgICAgICAgICAgICBgMmAgPSAiSWYgdGhpcyBpcyBoZXJlIGl0IG1lYW5zIGRhdGEgbm90IGZpbHRlcmVkIgogICAgICAgICAgICAgICAgICAgICkKCnBsbz1nZ3Bsb3QoZGF0YT1kYXRhSW5wdXQsIGFlcyh5PXRpbWVTcGVudCwgeD1hcy5mYWN0b3IoYXMubG9naWNhbChwaGFzZVQpKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbCA9IHJvdW5kKHRpbWVTcGVudCxkaWdpdHMgPSAxKSxncm91cD0xKSkgKwogIGdlb21fbGluZSgpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49dGltZVNwZW50LXNlLCB5bWF4PXRpbWVTcGVudCtzZSksIHdpZHRoPS4xKSArCiAgZ2VvbV9wb2ludChzaGFwZT0yMSwgc2l6ZT0zLCBmaWxsPSJ3aGl0ZSIpKwogIGxhYnModGl0bGU9IlRpbWUgU3BlbnQgc2VncmVnYXRlZCBieSBzb2x2YW5iaWxpdHkiLHg9IkluIFBoYXNlIFRyYW5zaXRpb24/Iix5PSJUaW1lIFNwZW50IikrCiAgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSksIGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlPTAsaGp1c3Q9MC41KSkrCiAgZ2VvbV90ZXh0KGhqdXN0PS0wLjUsIGNvbG91cj0iYmxhY2siKSsKICBmYWNldF9ncmlkKC5+c29sLCBsYWJlbGxlciA9IGFzX2xhYmVsbGVyKHNvbF9uYW1lcykpCgpvdXRwdXROYW1lID0gInRzcF90aW1lXzAzX2ciCnBsb3RFeHBvcnQocGxvLG91dHB1dE5hbWUsZm9sZGVyT3V0X2ZpZ3VyZXMpCmBgYAoKYHRpbWVTcGVudCB+IHBoYXNlVCArIHNvbCArIHBoYXNlVDpzb2wgKyAoMXxwSUQpYAoKYGBge3J9CmRhdGFJbnB1dD0gZGF0YVRyaWFsX1RTUF9UaW1lCiNsb2dpc3RpYyB3aXRoIHJhbmRvbSBlZmZlY3RzIChpbnRlcmNlcHQpCgpkYXRhSW5wdXQkcGhhc2VUID0gYXMuZmFjdG9yKGRhdGFJbnB1dCRwaGFzZVQpCmRhdGFJbnB1dCRzb2wgPSBhcy5mYWN0b3IoZGF0YUlucHV0JHNvbCkKCiMgVFRUT0RPCnJhbmRvbUludGVyY2VwdCA9IGJybTIodGltZVNwZW50X3BjdCB8IGNlbnMoY2Vuc29yZWRfdGltZSkgfiBwaGFzZVQgKyBzb2wgKyBwaGFzZVQ6c29sICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LCAKICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLAogICAgICAgICAgICAgICAgICAgICAgcmVmcmVzaCA9IDAsIGl0ZXIgPSBpdGVyc19oaWdoKQoKdGFibGVOYW1lPSJ0c3BfdGltZV8wM19yIgpzYXZlX3N1bW1hcmlzZV9tb2RlbChyYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKCmBgYAoKTWFyZ2lhbmwgRWZmZWN0cwoKYGBge3J9CiNtYXJnaW5hbF9lZmZlY3RzKHJhbmRvbUludGVyY2VwdCkKcGxvdChtYXJnaW5hbF9lZmZlY3RzKGFsbE1vZGVsc1tbInRzcF90aW1lXzAzX3IiXV0pLCBwbG90ID0gVFJVRSwgYXNrID0gRkFMU0UpCgpgYGAKCiMjIyBTYXRpc2ZpYWJpbGl0eQoKYGBge3J9CiNzdDA2CmRhdGFJbnB1dD0gZGF0YVRyaWFsX1RTUF9UaW1lCiNsb2dpc3RpYyB3aXRoIHJhbmRvbSBlZmZlY3RzIChpbnRlcmNlcHQpCiNkYXRhSW5wdXQkc29sID1hcy5mYWN0b3IoZGF0YUlucHV0JHNvbCkKCnJhbmRvbUludGVyY2VwdCA9IGJybTIodGltZVNwZW50X3BjdCB8IGNlbnMoY2Vuc29yZWRfdGltZSkgfiBzb2wgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwLCBpdGVyID0gaXRlcnNfaGlnaCkKCnRhYmxlTmFtZT0idHNwX3RpbWVfMDNfcl9CIgpzYXZlX3N1bW1hcmlzZV9tb2RlbChyYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKCmBgYAoKIyMjIFJlZ2lvbiBlZmZlY3Qgb24gdGltZS1vbi10YXNrIChDb25zdHJhaW5lZG5lc3MpCgpgYGB7ciAsIGZpZy5hbGlnbj0nY2VudGVyJ30KZGF0YUlucHV0PWRhdGFUcmlhbF9UU1BfVGltZSAKCmRhdGFJbnB1dDI9ZGF0YUlucHV0ICU+JSBncm91cF9ieShyZWdpb24scElEKSU+JXN1bW1hcmlzZSh0aW1lU3BlbnQxPW1lYW4odGltZVNwZW50KSklPiV1bmdyb3VwKCklPiVncm91cF9ieShyZWdpb24pJT4lc3VtbWFyaXNlKHRpbWVTcGVudD1tZWFuKHRpbWVTcGVudDEpLHNlPXNlKHRpbWVTcGVudDEpKSU+JXVuZ3JvdXAoKQoKZGF0YUlucHV0MiRyZWdpb24gPC0gZmFjdG9yKGRhdGFJbnB1dDIkcmVnaW9uLCBsZXZlbHMgPSBjKCdVbmRlcmNvbnN0cmFpbmVkJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdQaGFzZSBUcmFuc2l0aW9uJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdPdmVyY29uc3RyYWluZWQnKSkKCnBsbz0gZ2dwbG90KGRhdGE9ZGF0YUlucHV0MiwgYWVzKHk9dGltZVNwZW50LCB4PXJlZ2lvbiwgbGFiZWwgPSByb3VuZCh0aW1lU3BlbnQsZGlnaXRzID0gMSkpKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49dGltZVNwZW50LXNlLCB5bWF4PXRpbWVTcGVudCtzZSksIHdpZHRoPS4xKSsKICBsYWJzKHRpdGxlPSJ0aW1lIFNwZW50IGJ5IHJlZ2lvbiIseD0iUmVnaW9uIix5PSJ0aW1lIFNwZW50IikrCiAgZ2VvbV90ZXh0KGhqdXN0PTAuNSx2anVzdCA9IDUsIGNvbG91cj0id2hpdGUiKSArCiAgdGhlbWVfbGlnaHQoKSsKICB0aGVtZShwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpKQoKb3V0cHV0TmFtZSA9ICJ0c3BfdGltZV8wNF9nIgpwbG90RXhwb3J0KHBsbyxvdXRwdXROYW1lLGZvbGRlck91dF9maWd1cmVzKQoKI1N0YXRzIHRlc3QgZm9yIHRpbWUgaW4gYW5kIG91dCBvZiBwaGFzZSB0cmFuc2l0aW9uOiBBTk9WQQpkYXRhSW5wdXQkb3ZlckNvbnN0cmFpbmVkPSAoZGF0YUlucHV0JHJlZ2lvbj09J092ZXJjb25zdHJhaW5lZCcpCmRhdGFJbnB1dCR1bmRlckNvbnN0cmFpbmVkPSAoZGF0YUlucHV0JHJlZ2lvbj09J1VuZGVyY29uc3RyYWluZWQnKQpgYGAKCmBgYHtyfQpyYW5kb21JbnRlcmNlcHQgPSBicm0yKHRpbWVTcGVudF9wY3QgfCBjZW5zKGNlbnNvcmVkX3RpbWUpIH4gb3ZlckNvbnN0cmFpbmVkICsgdW5kZXJDb25zdHJhaW5lZCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwgCiAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywgcmVmcmVzaCA9IDAsIGl0ZXIgPSBpdGVyc19oaWdoKQoKdGFibGVOYW1lPSJ0c3BfdGltZV8wNF9nX0EiCnNhdmVfc3VtbWFyaXNlX21vZGVsKHJhbmRvbUludGVyY2VwdCwgdGFibGVOYW1lKQoKYGBgCgpJcyB0aGVyZSBhIGRpZmZlcmVuY2UgYmV0d2VlbiB0aW1lLW9uLXRhc2sgYmV0d2VlbiBvdmVyY29uc3RyYWluZWQgYW5kIHRoZSB1bmRlcmNvbnN0cmFpbmVkIHJlZ2lvbj8KCmBgYHtyfQpmaXQgPSBoeXBvdGhlc2lzKGFsbE1vZGVsc1tbInRzcF90aW1lXzA0X2dfQSJdXSwib3ZlckNvbnN0cmFpbmVkVFJVRT11bmRlckNvbnN0cmFpbmVkVFJVRSIsIHNlZWQ9c2VlZF9icm1zKQpwcmludChmaXQpCmhkaShmaXQkc2FtcGxlcyxjaT0wLjk1KQpgYGAKCiMjIyBOdW1iZXIgb2Ygc29sdXRpb24gd2l0bmVzc2VzIHRoYXQgc2F0aXNmeSB0aGUgeG9uc3RyYWludHMgeyN0c3BfdGltZV9uc29sfQoKCmBgYHtyICwgZmlnLmFsaWduPSdjZW50ZXInfQpkYXRhSW5wdXQ9ZGF0YVRyaWFsX1RTUF9UaW1lCgojUGxvdHMgblNvbHV0aW9ucyAoeCkgdnMuIEFjY3VyYWN5ICh5KQpkYXRhSW5wdXQzID0gZGF0YUlucHV0ICU+JSBncm91cF9ieShuU29sdXRpb25zLHBJRCxwaGFzZVQpJT4lc3VtbWFyaXNlKHRpbWVTcGVudDE9bWVhbih0aW1lU3BlbnQpKSU+JXVuZ3JvdXAoKSU+JWdyb3VwX2J5KG5Tb2x1dGlvbnMscGhhc2VUKSU+JXN1bW1hcmlzZSh0aW1lU3BlbnQ9bWVhbih0aW1lU3BlbnQxKSxzZT1zZSh0aW1lU3BlbnQxKSklPiV1bmdyb3VwKCkKCmRhdGFJbnB1dDMkc29sID0gZGF0YUlucHV0MyRuU29sdXRpb25zPj0xCmRhdGFJbnB1dDMkcGhhc2VUID0gcmVjb2RlKGRhdGFJbnB1dDMkcGhhc2VULCAnMCcgPSAiTG93IElDIiwgJzEnID0gIkhpZ2ggSUMiKQoKZGF0YUlucHV0MyRuU29sdXRpb25zID0gZGF0YUlucHV0MyRuU29sdXRpb25zICsxIAoKcGxvPSBnZ3Bsb3QoZGF0YT1kYXRhSW5wdXQzLCBhZXMoeT10aW1lU3BlbnQsIHg9blNvbHV0aW9ucykpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPXRpbWVTcGVudC1zZSwgeW1heD10aW1lU3BlbnQrc2UpLCB3aWR0aD0uMSkrCiAgZ2VvbV9wb2ludChzaGFwZT0yMywgc2l6ZT0zLCBmaWxsPSJyZWQiKSsKICBsYWJzKHRpdGxlPSJUaW1lIFNwZW50IGFuZCB0aGUgTnVtYmVyIG9mIFNvbHV0aW9ucyIsCiAgICAgICB4PSJOdW1iZXIgb2YgICBTb2x1dGlvbnMiLHk9IlRpbWUgU3BlbnQiKSsKICAjY29vcmRfY2FydGVzaWFuKHlsaW0gPSBjKDAuNSwxKSkrCiAgdGhlbWVfbGlnaHQoKSsKICBzY2FsZV94X2xvZzEwKCkrCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSxzdHJpcC50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCkpKwogIGZhY2V0X2dyaWQocGhhc2VUfnNvbCwgc2NhbGVzID0gImZyZWVfeCIsIHNwYWNlID0gImZyZWVfeCIpKwogIGdlb21fc21vb3RoKGRhdGE9ZGF0YUlucHV0MywgYWVzKHk9dGltZVNwZW50LCB4PW5Tb2x1dGlvbnMpLG1ldGhvZD1nbG0sCiAgICAgICAgICAgICAgc2U9RkFMU0UsZnVsbHJhbmdlPVRSVUUsbGluZXR5cGUgPSAiZGFzaGVkIikKCm91dHB1dE5hbWUgPSAidHNwX25zb2xzX3RpbWVfZyIKcGxvdEV4cG9ydChwbG8sb3V0cHV0TmFtZSxmb2xkZXJPdXRfZmlndXJlcykKCmBgYAoKYGBge3J9CmRhdGFJbnB1dD1kYXRhVHJpYWxfVFNQX1RpbWUKCmRhdGFJbnB1dCA9IGRhdGFJbnB1dCAlPiUgZmlsdGVyKHNvbD09MSkKZGF0YUlucHV0JG5Tb2x1dGlvbnNfbG9nID0gbG9nKGRhdGFJbnB1dCRuU29sdXRpb25zKQoKbGluUmFuZG9tSW50ZXJjZXB0ID0gYnJtMih0aW1lU3BlbnRfcGN0IHwgY2VucyhjZW5zb3JlZF90aW1lKSB+IHBoYXNlVCArIG5Tb2x1dGlvbnNfbG9nICsgcGhhc2VUOm5Tb2x1dGlvbnNfbG9nICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LAogICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwLCBpdGVyID0gaXRlcnNfaGlnaCkKCnRhYmxlTmFtZT0idHNwX25zb2xzX3RpbWVfciIKc2F2ZV9zdW1tYXJpc2VfbW9kZWwobGluUmFuZG9tSW50ZXJjZXB0LCB0YWJsZU5hbWUpCmBgYAoKVGhpcyBjYWxjdWxhdGVzIHRoZSBzaWduaWZpY2FuY2Ugb2YgdGhlIG51bWJlciBvZiB3aXRuZXNzZXMgYmV0YShzbG9wZSkgZm9yIGluc3RhbmNlIHdpdGggaGlnaCBUQ0MuCgpgYGB7cn0KI1RoaXMgdmVyc2lvbiByZWNvZGVzIHBoYXNlVCB0byBPdXRwaGFzZVQsIHRvIAoKZml0ID0gaHlwb3RoZXNpcyhhbGxNb2RlbHNbWyJ0c3BfbnNvbHNfdGltZV9yIl1dLCJuU29sdXRpb25zX2xvZyArIHBoYXNlVDpuU29sdXRpb25zX2xvZyA9IDAiLCBzZWVkPXNlZWRfYnJtcykKCnByaW50KGZpdCkKCmhkaShmaXQkc2FtcGxlcyxjaT0wLjk1KQoKYGBgCgpNYXJnaW5hbCBFZmZlY3RzCgpgYGB7cn0KI21hcmdpbmFsX2VmZmVjdHMocmFuZG9tSW50ZXJjZXB0KQpwbG90KG1hcmdpbmFsX2VmZmVjdHMoYWxsTW9kZWxzW1sidHNwX25zb2xzX3RpbWVfciJdXSksIHBsb3QgPSBUUlVFLCBhc2sgPSBGQUxTRSkKYGBgCgojIyMjIE5vLiBvZiB3aXRuZXNzZXMgKFJlZ3Jlc3NlZCBhbG9uZSkKCmBgYHtyfQojc3QwNwpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9UU1BfVGltZQpkYXRhSW5wdXQgPSBkYXRhSW5wdXQgJT4lIGZpbHRlcihzb2w9PTEpCiNsb2dpc3RpYyB3aXRoIHJhbmRvbSBlZmZlY3RzIChpbnRlcmNlcHQpCiNkYXRhSW5wdXQkc29sID1hcy5mYWN0b3IoZGF0YUlucHV0JHNvbCkKZGF0YUlucHV0JG5Tb2x1dGlvbnNfbG9nID0gbG9nKGRhdGFJbnB1dCRuU29sdXRpb25zKQoKcmFuZG9tSW50ZXJjZXB0ID0gYnJtMih0aW1lU3BlbnRfcGN0IHwgY2VucyhjZW5zb3JlZF90aW1lKSB+ICBuU29sdXRpb25zX2xvZyArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwgCiAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywgcmVmcmVzaCA9IDAsIGl0ZXIgPSBpdGVyc19oaWdoKQoKdGFibGVOYW1lPSJ0c3BfbnNvbHNfdGltZV9yX0IiCnNhdmVfc3VtbWFyaXNlX21vZGVsKHJhbmRvbUludGVyY2VwdCwgdGFibGVOYW1lKQoKYGBgCgpgYGB7cn0KCiNkYXRhSW5wdXQzCm1lYW5fYWNjID0gZGF0YUlucHV0ICU+JSBncm91cF9ieShpbnN0YW5jZU51bWJlcixuU29sdXRpb25zLG5Tb2x1dGlvbnNfbG9nLCBzb2wscGhhc2VUKSAlPiUKICBzdW1tYXJpc2UoYWNjdXJhY3k9bWVhbihjb3JyZWN0KSwKICAgICAgICAgICAgdGltZVNwZW50X21lZCA9bWVkaWFuKHRpbWVTcGVudCkpIAoKbG9naXRSYW5kb21JbnRlcmNlcHQgPSBhbGxNb2RlbHNbWyd0c3BfbnNvbHNfdGltZV9yX0InXV0KcHAgID0gcGxvdChjb25kaXRpb25hbF9lZmZlY3RzKGxvZ2l0UmFuZG9tSW50ZXJjZXB0KSwgcGxvdCA9IEZBTFNFLCBhc2sgPSBGQUxTRSkKCnBwJG5Tb2x1dGlvbnMgKyAKICBnZW9tX3BvaW50KGRhdGE9bWVhbl9hY2MsYWVzKHggPSBuU29sdXRpb25zX2xvZywgeSA9IHRpbWVTcGVudF9tZWQvVFNQVGFza01heFRpbWUpLGluaGVyaXQuYWVzID0gRkFMU0UpCgoKYGBgCgpgYGB7cn0KIyBJbXByb3ZpbmcgdGhlIHBsb3QKCmRhdGFJbnB1dCRuU29sdXRpb25zX2xvZ19iaW4gPSBjdXRfd2lkdGgoZGF0YUlucHV0JG5Tb2x1dGlvbnNfbG9nLCB3aWR0aD0xLCBib3VuZGFyeSA9MCxsYWJlbHM9RkFMU0UpCmRhdGFJbnB1dCRuU29sdXRpb25zX2xvZ19iaW4gPSAoZGF0YUlucHV0JG5Tb2x1dGlvbnNfbG9nX2JpbioxKS0wLjUKCnNpemVfYmlnID0gMjAKc2l6ZV9zbWFsbCA9IDE2CnNpemVfc3MgPSAxMApzaXplX3hzID0gNwoKcHBfcGxvdCA9IHBwJG5Tb2x1dGlvbnNfbG9nCnBwX3Bsb3QkbGF5ZXJzW1sxXV0kZ2VvbV9wYXJhbXMkc2UgPSBGQUxTRQpwcF9wbG90JGxheWVyc1tbMV1dJGFlc19wYXJhbXMkY29sb3VyPSIjNTc3NTkwIgoKcHBfcGxvdCRsYXllcnMgPC0gYyhnZW9tX2JveHBsb3QoZGF0YT1kYXRhSW5wdXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBuU29sdXRpb25zX2xvZ19iaW4sIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cCA9IG5Tb2x1dGlvbnNfbG9nX2JpbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSB0aW1lU3BlbnRfcGN0KSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5oZXJpdC5hZXMgPSBGQUxTRSx3aWR0aD0wLjcpLAogICAgICAgICAgICAgICAgICAgICAgICBnZW9tX3BvaW50KGRhdGE9bWVhbl9hY2MsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gblNvbHV0aW9uc19sb2csIHkgPSB0aW1lU3BlbnRfbWVkL1RTUFRhc2tNYXhUaW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2w9YXMuZmFjdG9yKHNvbCksIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpLCBzaXplPTIuNSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5oZXJpdC5hZXMgPSBGQUxTRSksCiAgICAgICAgICAgICAgICAgICAgICAgICBwcF9wbG90JGxheWVycykKCnBsbyA9IHBwX3Bsb3QgKwogIHhsYWIoIk51bWJlciBvZiBzb2x1dGlvbiBXaXRuZXNzZXMiKSsjZXhwcmVzc2lvbihJQ1tleHBvc3RdKSkrCiAgeWxhYigiVGltZS1vbi10YXNrIikrCiAgc2NhbGVfc2hhcGVfbWFudWFsKG5hbWU9IiIsdmFsdWVzID0gYygxNywxNikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwobmFtZT0iIix2YWx1ZXMgPSBjKCIxIj0iIzkwQkU2RCIsIjAiPSIjRjk0MTQ0IikpKyNjKCAiI0ZDNEUwNyIsIiNFN0I4MDAiKQogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgeWxpbSgwLCAxKSsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYyhsb2coMSksbG9nKDEwKSxsb2coMTAwKSxsb2coMTAwMCksbG9nKDEwMDAwKSksCiAgICAgICAgICAgICAgICAgICAgIGxpbWl0cyA9YygwLE5BKSxsYWJlbHMgPSBjKCIxIiwiMTAiLCIxMDAiLCIxMDAwIiwiMTAwMDAiKSApKwogIGd1aWRlcyhzaGFwZSA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzKSkpCgpwbG8KZ2dzYXZlKHBhc3RlMChmb2xkZXJPdXRfZmlndXJlcywiL053aXRfVFNQX3RpbWUucGRmIikscGxvLHdpZHRoID0gNixoZWlnaHQgPTYsdW5pdHM9ImluIikKYGBgCgpgYGB7cn0KIyBJbXByb3ZpbmcgdGhlIHBsb3QKc2l6ZV9iaWcgPSAyMApzaXplX3NtYWxsID0gMTYKc2l6ZV9zcyA9IDEwCnNpemVfeHMgPSA3CgpwcF9wbG90ID0gcHAkblNvbHV0aW9uc19sb2cKcHBfcGxvdCRsYXllcnNbWzFdXSRnZW9tX3BhcmFtcyRzZSA9IFRSVUUKcHBfcGxvdCRsYXllcnNbWzFdXSRhZXNfcGFyYW1zJGNvbG91cj0iIzU3NzU5MCIKCnBwX3Bsb3QkbGF5ZXJzIDwtIGMoZ2VvbV9wb2ludChkYXRhPWRhdGFJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gblNvbHV0aW9uc19sb2csIHkgPSB0aW1lU3BlbnRfcGN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpLCBzaXplPTAuNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbHBoYSA9IDAuNSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5oZXJpdC5hZXMgPSBGQUxTRSksCiAgICAgICAgICAgICAgICAgICAgZ2VvbV9qaXR0ZXIoZGF0YT1tZWFuX2FjYywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBuU29sdXRpb25zX2xvZywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSB0aW1lU3BlbnRfbWVkL1RTUFRhc2tNYXhUaW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2w9YXMuZmFjdG9yKHNvbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpLCBzaXplPTIuNSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5oZXJpdC5hZXMgPSBGQUxTRSksCiAgICAgICAgICAgICAgICAgICAgICAgICBwcF9wbG90JGxheWVycykKCnBsbyA9IHBwX3Bsb3QgKwogIHhsYWIoIk51bWJlciBvZiBzb2x1dGlvbiBXaXRuZXNzZXMiKSsjZXhwcmVzc2lvbihJQ1tleHBvc3RdKSkrCiAgeWxhYigiVGltZS1vbi10YXNrIikrCiAgc2NhbGVfc2hhcGVfbWFudWFsKG5hbWU9IiIsdmFsdWVzID0gYygxNywxNikpICsKICBzY2FsZV9jb2xvcl9tYW51YWwobmFtZT0iIix2YWx1ZXMgPSBjKCIxIj0iIzkwQkU2RCIsIjAiPSIjRjk0MTQ0IikpKyNjKCAiI0ZDNEUwNyIsIiNFN0I4MDAiKQogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgIyB5bGltKDAsIDEuMSkrCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwwLjI1LDAuNSwwLjc1LDEpLGxpbWl0cyA9YygwLDEuMSkpKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKGxvZygxKSxsb2coMTApLGxvZygxMDApLGxvZygxMDAwKSxsb2coMTAwMDApKSwKICAgICAgICAgICAgICAgICAgICAgbGltaXRzID1jKGxvZygyKSxOQSksbGFiZWxzID0gYygiMSIsIjEwIiwiMTAwIiwiMTAwMCIsIjEwMDAwIikgKSsKICBndWlkZXMoc2hhcGUgPSBndWlkZV9sZWdlbmQob3ZlcnJpZGUuYWVzID0gbGlzdChzaXplID0gMykpKQoKcGxvCmdnc2F2ZShwYXN0ZTAoZm9sZGVyT3V0X2ZpZ3VyZXMsIi9Od2l0X1RTUF90aW1lMi5wZGYiKSxwbG8sd2lkdGggPSA2LGhlaWdodCA9Nix1bml0cz0iaW4iKQpgYGAKCiMjIyBJQ19leHBvc3QgeyN0c3BfdGltZV9JQ2V4cG9zdH0KCmBgYHtyLCBmaWcuYWxpZ249J2NlbnRlcid9CmRhdGFJbnB1dCA9IGRhdGFUcmlhbF9UU1BfVGltZQoKIyBTdW1tYXJpc2UgdGhlIGRhdGEgdG8gcGxvdAptZWFuX2FjY3VyYWN5X3RpbWUgPSBkYXRhSW5wdXQgJT4lIAogIGdyb3VwX2J5KGluc3RhbmNlTnVtYmVyLCBzb2wsIElDZXhwb3N0LCBwaGFzZVQsIG5Tb2x1dGlvbnMpICU+JSAKICBzdW1tYXJpc2UoYWNjdXJhY3kgPSBtZWFuKGNvcnJlY3QpLCAKICAgICAgICAgICAgdGltZVNwZW50X21lZCA9IG1lZGlhbih0aW1lU3BlbnQpLAogICAgICAgICAgICB0aW1lU3BlbnQgPSBtZWFuKHRpbWVTcGVudCkpCgpnZ3Bsb3QobWVhbl9hY2N1cmFjeV90aW1lLGFlcyh4ID0gSUNleHBvc3QsIHkgPSB0aW1lU3BlbnQpKSsKICBnZW9tX3BvaW50KCkgKwogIHRoZW1lX2xpZ2h0KCkgKwogIHN0YXRfc21vb3RoKGZvcm11bGEgPSAgeSB+IEkoeF4wLjAxKSwgbWV0aG9kPSJsbSIsIHNlPSBGQUxTRSkrCiAgeGxhYigiSUNfZXhwb3N0IikrCiAgeWxhYigiVGltZSBTcGVudCIpCgpgYGAKCmBgYHtyfQptb2RlbF9JQ2V4cG9zdCA9IGJybTIodGltZVNwZW50X3BjdCB8IGNlbnMoY2Vuc29yZWRfdGltZSkgfiBJQ2V4cG9zdCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZnJlc2ggPSAwLCBpdGVyID0gaXRlcnNfaGlnaCkKCnRhYmxlTmFtZT0ndHNwX3RpbWVfaWNleHBvc3QnCnNhdmVfc3VtbWFyaXNlX21vZGVsKG1vZGVsX0lDZXhwb3N0LCB0YWJsZU5hbWUpCgoKYGBgCgoKYGBge3J9Cm1lYW5fYWNjdXJhY3lfdGltZSRjb3JyZWN0PSBtZWFuX2FjY3VyYWN5X3RpbWUkYWNjdXJhY3kKCm1vZGVsX0lDZXhwb3N0ID0gYWxsTW9kZWxzW1sndHNwX3RpbWVfaWNleHBvc3QnXV0KcHAgID0gcGxvdChjb25kaXRpb25hbF9lZmZlY3RzKG1vZGVsX0lDZXhwb3N0KSwgcGxvdCA9IEZBTFNFLCBhc2sgPSBGQUxTRSkKCmRhdGFJbnB1dCRJQ2V4cG9zdF9iaW4gPSBjdXRfd2lkdGgoZGF0YUlucHV0JElDZXhwb3N0LCB3aWR0aD0wLjAyLCBib3VuZGFyeSA9MCxsYWJlbHM9RkFMU0UpCmRhdGFJbnB1dCRJQ2V4cG9zdF9iaW4gPSAoZGF0YUlucHV0JElDZXhwb3N0X2JpbiowLjAyKS0wLjAxCgpwcF9wbG90ID0gcHAkSUNleHBvc3QKCnBwX3Bsb3QkbGF5ZXJzIDwtIGMoZ2VvbV9wb2ludChkYXRhPW1lYW5fYWNjdXJhY3lfdGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZXMoeCA9IElDZXhwb3N0LCB5ID0gdGltZVNwZW50X21lZC9UU1BUYXNrTWF4VGltZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5oZXJpdC5hZXMgPSBGQUxTRSksCiAgICAgICAgICAgICAgICAgICAgICAgICBwcF9wbG90JGxheWVycykKCnBwX3Bsb3QKCmBgYAoKYGBge3J9CnBwX3Bsb3QgPSBwcCRJQ2V4cG9zdAoKcHBfcGxvdCRsYXllcnNbWzFdXSRnZW9tX3BhcmFtcyRzZSA9IFRSVUUKcHBfcGxvdCRsYXllcnNbWzFdXSRhZXNfcGFyYW1zJGNvbG91cj0iIzU3NzU5MCIKCnBwX3Bsb3QkbGF5ZXJzIDwtIGMoZ2VvbV9wb2ludChkYXRhPWRhdGFJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gSUNleHBvc3QsIHkgPSB0aW1lU3BlbnRfcGN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpLCBzaXplPTAuNCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjY29sPWFzLmZhY3Rvcihzb2wpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFscGhhID0gMC4zKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFKSwKICAgICAgICAgICAgICAgICAgICBnZW9tX2ppdHRlcihkYXRhPW1lYW5fYWNjdXJhY3lfdGltZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBJQ2V4cG9zdCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHkgPSB0aW1lU3BlbnRfbWVkL1RTUFRhc2tNYXhUaW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2w9YXMuZmFjdG9yKHNvbCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpLCBzaXplPTIuNSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5oZXJpdC5hZXMgPSBGQUxTRSksCiAgICAgICAgICAgICAgICAgICAgICAgICBwcF9wbG90JGxheWVycykKCnNpemVfYmlnID0gMjAKc2l6ZV9zbWFsbCA9IDE2CnNpemVfc3MgPSAxMApzaXplX3hzID0gNwoKcGxvID0gcHBfcGxvdCArCiAgeGxhYigiSW5zdGFuY2UgQ29tcGxleGl0eSAoSUMpIikrI2V4cHJlc3Npb24oSUNbZXhwb3N0XSkpKwogIHlsYWIoIlRpbWUtb24tdGFzayIpKwogIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lPSIiLHZhbHVlcyA9IGMoMTcsMTYpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWU9IiIsdmFsdWVzID0gYygiMSI9IiM5MEJFNkQiLCIwIj0iI0Y5NDE0NCIpKSsjYyggIiNGQzRFMDciLCIjRTdCODAwIikKICAjIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lPSJJQyIsdmFsdWVzID0gYygyLCA4KSkrCiAgIyBzY2FsZV9jb2xvcl9tYW51YWwobmFtZT0iU29sdXRpb24iLHZhbHVlcyA9IGMoInJlZCIsICJibHVlIikpKwogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IGMoMCwwLjI1LDAuNSwwLjc1LDEpLGxpbWl0cyA9YygwLDEuMSkpKwogIGd1aWRlcyhzaGFwZSA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzKSkpCgpwbG8KZ2dzYXZlKHBhc3RlMChmb2xkZXJPdXRfZmlndXJlcywiL0lDX1RTUF90aW1lMS5wZGYiKSxwbG8sd2lkdGggPSA2LGhlaWdodCA9Nix1bml0cz0iaW4iKQoKYGBgCgojIyBUaW1lLW9uLXRhc2sgYW5kIGFjY3VyYWN5IHsjdHNwX3RpbWVfYWNjfQoKYGBge3IsIGZpZy5hbGlnbj0nY2VudGVyJ30KCmRhdGFJbnB1dD0gZGF0YVRyaWFsX1RTUF9UaW1lICU+JSBncm91cF9ieShjb3JyZWN0LHBJRCkgJT4lIHN1bW1hcmlzZSh0aW1lU3BlbnRNZWFucz1tZWFuKHRpbWVTcGVudCkpICU+JSB1bmdyb3VwKCkgJT4lIGdyb3VwX2J5KGNvcnJlY3QpICU+JQogIHN1bW1hcmlzZSh0aW1lPW1lYW4odGltZVNwZW50TWVhbnMpLHNlPXNlKHRpbWVTcGVudE1lYW5zKSklPiV1bmdyb3VwKCkKCnBsbyA9IGdncGxvdChkYXRhPWRhdGFJbnB1dCwgYWVzKHk9dGltZSwgeD1hcy5mYWN0b3IoYXMubG9naWNhbChjb3JyZWN0KSksIGxhYmVsID0gcm91bmQodGltZSxkaWdpdHMgPSAyKSxncm91cD0xKSkgKwogIGdlb21fbGluZSgpKwogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49dGltZS1zZSwgeW1heD10aW1lK3NlKSwgd2lkdGg9LjEpICsKICBnZW9tX3BvaW50KHNoYXBlPTIxLCBzaXplPTMsIGZpbGw9IndoaXRlIikrCiAgbGFicyh0aXRsZT0iVGltZSBTcGVudCBvbiBDb3JyZWN0L0luY29ycmVjdCBpbnN0YW5jZXMiLHg9IkFuc3dlciBDb3JyZWN0PyIseT0iVGltZSBTcGVudCIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGU9MCxoanVzdD0wLjUpKSsKICBnZW9tX3RleHQoaGp1c3Q9LTAuNSwgY29sb3VyPSJibGFjayIpCgpvdXRwdXROYW1lID0gInRzcF90aW1lXzA4X2dfQiIKcGxvdEV4cG9ydChwbG8sb3V0cHV0TmFtZSxmb2xkZXJPdXRfZmlndXJlcykKCmBgYAoKCmBjb3JyZWN0IH4gdGltZVNwZW50ICsgKDF8cElEKWAKCmBgYHtyLCBmaWcuYWxpZ249J2NlbnRlcid9CmRhdGFJbnB1dCA9IGRhdGFUcmlhbF9UU1BfVGltZQojU3RhdHMgdGVzdCBmb3IgdGltZSBpbiBhbmQgb3V0IG9mIHBoYXNlIHRyYW5zaXRpb246IEFOT1ZBCmFub3ZhTW9kZWw9YW92KHRpbWVTcGVudH5jb3JyZWN0K0Vycm9yKHBJRC9jb3JyZWN0KSxkYXRhSW5wdXQpCmFub3ZhUFZhbHVlPXN1bW1hcnkoYW5vdmFNb2RlbClbWzJdXVtbMV1dW1snUHIoPkYpJ11dW1sxXV0KcHJpbnQocGFzdGUoIlAtdmFsdWUgZm9yIG9uZSB3YXkgQU5PVkE6IixzaWduaWYoYW5vdmFQVmFsdWUsZGlnaXRzPTMpKSkKCiNTdGF0cyB0ZXN0IGZvciB0aW1lIGZvciBjb3JyZWN0L2luY29ycmVjdCBhbnN3ZXJzCmxvZ2l0UmFuZG9tSW50ZXJjZXB0ID0gYnJtMihjb3JyZWN0IH4gdGltZVNwZW50X3BjdCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhbWlseT1iZXJub3VsbGkobGluaz0ibG9naXQiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwKQoKdGFibGVOYW1lPSJ0c3BfdGltZV8wOF9yX0IiCnNhdmVfc3VtbWFyaXNlX21vZGVsKGxvZ2l0UmFuZG9tSW50ZXJjZXB0LCB0YWJsZU5hbWUpCmBgYAoKTWFyZ2luYWwgRWZmZWN0cyB7XCN0c3BfdGltZV9hY2N9CgpgYGB7cn0KcGxvdChtYXJnaW5hbF9lZmZlY3RzKGFsbE1vZGVsc1tbInRzcF90aW1lXzA4X3JfQiJdXSksIHBsb3QgPSBUUlVFLCBhc2sgPSBGQUxTRSkKYGBgCgoKIyMgTnVtYmVyIG9mIENsaWNrcwoKIyMjIyBTYXRpc2ZpYWJpbGl0eQoKYGBge3IgLCBmaWcuYWxpZ249J2NlbnRlcid9CmRhdGFJbnB1dD1kYXRhVHJpYWxfVFNQX2NsaWNrcwoKIyBCT1hQTE9UCnBsbz0gZ2dwbG90KGRhdGE9ZGF0YUlucHV0LCBhZXMoeT1uX2NsaWNrcywgeD1yZWdpb24sIGxhYmVsID0gcm91bmQobl9jbGlja3MsZGlnaXRzID0gMCkpKSArCiAgZ2VvbV9ib3hwbG90KCkrCiAgbGFicyh4PSJSZWdpb24iLHk9Im5fY2xpY2tzIikrCiAgI2Nvb3JkX2NhcnRlc2lhbih5bGltID0gYygwLjUsMSkpKwogIGdlb21fdGV4dChoanVzdD0wLjUsdmp1c3QgPSA1LCBjb2xvdXI9IndoaXRlIikgKwogIHRoZW1lX2xpZ2h0KCkrCiAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfYmxhbmsoKSwgCiAgICAgICAgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSxwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkrCiAgZmFjZXRfZ3JpZCgufnNvbCkKCgpvdXRwdXROYW1lID0gJ3RzcF9jbGlja3NfMDBfZycKcGxvdEV4cG9ydChwbG8sb3V0cHV0TmFtZSxmb2xkZXJPdXRfZmlndXJlcykKCmBgYAoKYGBge3J9CnNpemVfYmlnID0gMjAKc2l6ZV9zbWFsbCA9IDE2CnNpemVfc3MgPSAxMApzaXplX3hzID0gNwoKZGF0YUlucHV0MiA9IGRhdGFUcmlhbF9UU1BfY2xpY2tzICU+JSAKICBtdXRhdGUocmVnaW9uID0gZmN0X3JlbGV2ZWwocmVnaW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiVW5kZXJjb25zdHJhaW5lZCIsICJQaGFzZSBUcmFuc2l0aW9uIiwgIk92ZXJjb25zdHJhaW5lZCIpKSU+JSAKICBtdXRhdGUoc29sPSBhcy5mYWN0b3Ioc29sKSkgJT4lIAogIG11dGF0ZShzb2wgPSBmY3RfcmVsZXZlbChzb2wsIjEiLCAiMCIpKQoKZGF0YUlucHV0MyA9IGRhdGFJbnB1dDIgJT4lIAogIGdyb3VwX2J5KGluc3RhbmNlTnVtYmVyLHJlZ2lvbixzb2wpICU+JSAKICBzdW1tYXJpc2Uobl9jbGlja3M9bWVhbihuX2NsaWNrcykpCgpwbG8gPSBnZ3Bsb3QoZGF0YUlucHV0MyxhZXMoeD1yZWdpb24seT1uX2NsaWNrcyxmaWxsPXNvbCkpKwogICMgZ2VvbV9ib3hqaXR0ZXIoYWVzKGZpbGw9cmVnaW9uKSxqaXR0ZXIuY29sb3IgPSBOQSxqaXR0ZXIuc2hhcGUgPSAyMSkrCiAgZ2VvbV9ib3hqaXR0ZXIoaml0dGVyLmNvbG9yID0gTkEsaml0dGVyLnNoYXBlID0gMjEsCiAgICAgICAgICAgICAgICAgaml0dGVyLnBhcmFtcyA9IGxpc3QoaGVpZ2h0PTAsc2VlZD0xMCksCiAgICAgICAgICAgICAgICAgb3V0bGllci5zaGFwZT0gTkEpKwogICAgICAgICAgICAgICAgICMsb3V0bGllci5zaGFwZSA9IDQsIG91dGxpZXIuc2l6ZT0wLjkpKwogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDAuNSkpKwogIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgID0iUmVnaW9uIiwKICAgICAgICAgICAgICAgICAgICBicmVha3M9YygiMSIsIjAiKSwKICAgICAgICAgICAgICAgICAgICBsYWJlbHM9YygiU2F0aXNmaWFibGUiLCJVbnNhdGlzZmlhYmxlIiksCiAgICAgICAgICAgICAgICAgICAgdmFsdWVzPWMoIiM5MEJFNkQiLCIjRjk0MTQ0IikpKwogIHhsYWIoIlR5cGljYWwgQ2FzZSBDb21wbGV4aXR5IChUQ0MpIikrCiAgeWxhYigiTnVtYmVyIG9mIGNsaWNrcyIpKwogIHRoZW1lX2NsYXNzaWMoKSsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9IHNpemVfYmlnKSwKICAgICAgIGF4aXMudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1zaXplX3NtYWxsKSwKICAgICAgIGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikrCiAgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMpKSkrCiAgeWxpbSgyMCwzMCkKCgpwbG8KZ2dzYXZlKHBhc3RlMChmb2xkZXJPdXRfZmlndXJlcywiL1RDQ19UU1BfbmNsaWNrcy5wZGYiKSxwbG8sd2lkdGggPSA3LGhlaWdodCA9Nix1bml0cz0iaW4iKQpgYGAKCmBgYHtyfQojTG9naXN0aWMgUmVncmVzc2lvbiBmb3IgSW4vT3V0IFBoYXNlIHRyYW5zaXRpb24KZGF0YUlucHV0PSBkYXRhVHJpYWxfVFNQX2NsaWNrcwoKI2xvZ2lzdGljIHdpdGggcmFuZG9tIGVmZmVjdHMgKGludGVyY2VwdCkKIyBUVFRPRE8KcmFuZG9tSW50ZXJjZXB0ID0gYnJtMihuX2NsaWNrcyB+IHNvbCArICgxfHBJRCksCiAgICAgICAgICAgICAgICAgICAgICBkYXRhPWRhdGFJbnB1dCwgCiAgICAgICAgICAgICAgICAgICAgICBjaGFpbnM9Y2hhaW5zX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBjb3JlcyA9IGNvcmVzX2JybXMsCiAgICAgICAgICAgICAgICAgICAgICBzZWVkPXNlZWRfYnJtcywgcmVmcmVzaCA9IDAsIGl0ZXIgPSBpdGVyc19oaWdoKQoKdGFibGVOYW1lPSJ0c3BfY2xpY2tzXzAxX3IiCnNhdmVfc3VtbWFyaXNlX21vZGVsKHJhbmRvbUludGVyY2VwdCwgdGFibGVOYW1lKQpgYGAKCiMjIyMgVENDCgpgYGB7cn0KI0xvZ2lzdGljIFJlZ3Jlc3Npb24gZm9yIEluL091dCBQaGFzZSB0cmFuc2l0aW9uCmRhdGFJbnB1dD0gZGF0YVRyaWFsX1RTUF9jbGlja3MKCiNsb2dpc3RpYyB3aXRoIHJhbmRvbSBlZmZlY3RzIChpbnRlcmNlcHQpCiMgVFRUT0RPCnJhbmRvbUludGVyY2VwdCA9IGJybTIobl9jbGlja3MgfiBwaGFzZVQgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwLCBpdGVyID0gaXRlcnNfaGlnaCkKCnRhYmxlTmFtZT0idHNwX2NsaWNrc18wMl9yIgpzYXZlX3N1bW1hcmlzZV9tb2RlbChyYW5kb21JbnRlcmNlcHQsIHRhYmxlTmFtZSkKYGBgCgojIyMjIyBBbmQgc2F0aXNmaWFiaWxpdHkKCmBgYHtyfQojTG9naXN0aWMgUmVncmVzc2lvbiBmb3IgSW4vT3V0IFBoYXNlIHRyYW5zaXRpb24KZGF0YUlucHV0PSBkYXRhVHJpYWxfVFNQX2NsaWNrcwoKI2xvZ2lzdGljIHdpdGggcmFuZG9tIGVmZmVjdHMgKGludGVyY2VwdCkKIyBUVFRPRE8KcmFuZG9tSW50ZXJjZXB0ID0gYnJtMihuX2NsaWNrcyB+IHJlZ2lvbisgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LCAKICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCwgaXRlciA9IGl0ZXJzX2hpZ2gpCgp0YWJsZU5hbWU9InRzcF9jbGlja3NfMDJCX3IiCnNhdmVfc3VtbWFyaXNlX21vZGVsKHJhbmRvbUludGVyY2VwdCwgdGFibGVOYW1lKQpgYGAKCmBgYHtyfQojTG9naXN0aWMgUmVncmVzc2lvbiBmb3IgSW4vT3V0IFBoYXNlIHRyYW5zaXRpb24KZGF0YUlucHV0PSBkYXRhVHJpYWxfVFNQX2NsaWNrcwoKI2xvZ2lzdGljIHdpdGggcmFuZG9tIGVmZmVjdHMgKGludGVyY2VwdCkKIyBUVFRPRE8KZGF0YUlucHV0JHBoYXNlVCA9IGFzLmZhY3RvcihkYXRhSW5wdXQkcGhhc2VUKQpkYXRhSW5wdXQkc29sID0gYXMuZmFjdG9yKGRhdGFJbnB1dCRzb2wpCnJhbmRvbUludGVyY2VwdCA9IGJybTIobl9jbGlja3MgfiBwaGFzZVQgKyBzb2wgKyBwaGFzZVQ6c29sICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LCAKICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCwgaXRlciA9IGl0ZXJzX2hpZ2gpCgp0YWJsZU5hbWU9InRzcF9jbGlja3NfMDJDX3IiCnNhdmVfc3VtbWFyaXNlX21vZGVsKHJhbmRvbUludGVyY2VwdCwgdGFibGVOYW1lKQpgYGAKCmBgYHtyfQpwcCAgPSBwbG90KGNvbmRpdGlvbmFsX2VmZmVjdHMoYWxsTW9kZWxzW1sidHNwX2NsaWNrc18wMkNfciJdXSksIHBsb3QgPSBUUlVFLCBhc2sgPSBGQUxTRSkKYGBgCgpgYGB7cn0KIyBzdGNoZQptb2RlbCA9IGFsbE1vZGVsc1tbJ3RzcF9jbGlja3NfMDJDX3InXV0KCmZpdCA9IGh5cG90aGVzaXMobW9kZWwsInNvbDEgKyBwaGFzZVQxOnNvbDE9MCIsIHNlZWQ9c2VlZF9icm1zKQoKcHJpbnQoZml0KQpgYGAKCiMjIyMgSUNleHBvc3QKCmBgYHtyfQojTG9naXN0aWMgUmVncmVzc2lvbiBmb3IgSW4vT3V0IFBoYXNlIHRyYW5zaXRpb24KZGF0YUlucHV0PSBkYXRhVHJpYWxfVFNQX2NsaWNrcwoKI2xvZ2lzdGljIHdpdGggcmFuZG9tIGVmZmVjdHMgKGludGVyY2VwdCkKIyBUVFRPRE8KcmFuZG9tSW50ZXJjZXB0ID0gYnJtMihuX2NsaWNrcyB+IElDZXhwb3N0ICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LCAKICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCwgaXRlciA9IGl0ZXJzX2hpZ2gpCgp0YWJsZU5hbWU9InRzcF9jbGlja3NfMDNfciIKc2F2ZV9zdW1tYXJpc2VfbW9kZWwocmFuZG9tSW50ZXJjZXB0LCB0YWJsZU5hbWUpCmBgYAoKYGBge3J9CnBwICA9IHBsb3QoY29uZGl0aW9uYWxfZWZmZWN0cyhhbGxNb2RlbHNbWyJ0c3BfY2xpY2tzXzAzX3IiXV0pLCBwbG90ID0gVFJVRSwgYXNrID0gRkFMU0UpCmBgYAoKYGBge3J9CmRhdGFJbnB1dD0gZGF0YVRyaWFsX1RTUF9jbGlja3MKIyBTdW1tYXJpc2UgdGhlIGRhdGEgdG8gcGxvdAptZWFuX25jbGlja3MgPSBkYXRhSW5wdXQgJT4lIAogIGdyb3VwX2J5KGluc3RhbmNlTnVtYmVyLCBzb2wsIElDZXhwb3N0LCBwaGFzZVQsIG5Tb2x1dGlvbnMpICU+JSAKICBzdW1tYXJpc2Uobl9jbGlja3MgPSBtZWRpYW4obl9jbGlja3MpKQoKbW9kZWxfSUNleHBvc3QgPSBhbGxNb2RlbHNbWyJ0c3BfY2xpY2tzXzAzX3IiXV0KcHAgID0gcGxvdChjb25kaXRpb25hbF9lZmZlY3RzKG1vZGVsX0lDZXhwb3N0KSwgcGxvdCA9IEZBTFNFLCBhc2sgPSBGQUxTRSkKCnBwJElDZXhwb3N0ICsKICBnZW9tX3BvaW50KGRhdGE9bWVhbl9uY2xpY2tzLGFlcyh4ID0gSUNleHBvc3QsIHkgPW5fY2xpY2tzKSxpbmhlcml0LmFlcyA9IEZBTFNFKQpgYGAKCmBgYHtyfQojIEltcHJvdmluZyB0aGUgcGxvdAojIEltcHJvdmluZyB0aGUgcGxvdApzaXplX2JpZyA9IDIwCnNpemVfc21hbGwgPSAxNgpzaXplX3NzID0gMTAKc2l6ZV94cyA9IDcKCnBwX3Bsb3QgPSBwcCRJQ2V4cG9zdApwcF9wbG90JGxheWVyc1tbMV1dJGdlb21fcGFyYW1zJHNlID0gRkFMU0UKcHBfcGxvdCRsYXllcnNbWzFdXSRhZXNfcGFyYW1zJGNvbG91cj0iIzU3NzU5MCIKCgoKcHBfcGxvdCRsYXllcnMgPC0gYyhnZW9tX2ppdHRlcihkYXRhPWRhdGFJbnB1dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFlcyh4ID0gSUNleHBvc3QsIHkgPSBuX2NsaWNrcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGFwZT1hcy5mYWN0b3IocGhhc2VUKSksIHNpemU9MC43LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFscGhhID0gMC4zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaGVyaXQuYWVzID0gRkFMU0UsaGVpZ2h0PTAuMiksCiAgICAgICAgICAgICAgICAgICAgZ2VvbV9wb2ludChkYXRhPW1lYW5fbmNsaWNrcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBJQ2V4cG9zdCwgeSA9IG5fY2xpY2tzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2w9YXMuZmFjdG9yKHNvbCksIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpKSxzaXplPTIuNSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmhlcml0LmFlcyA9IEZBTFNFKSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBwX3Bsb3QkbGF5ZXJzKQoKcGxvID0gcHBfcGxvdCArCiAgeGxhYigiSW5zdGFuY2UgQ29tcGxleGl0eSAoSUMpIikrI2V4cHJlc3Npb24oSUNbZXhwb3N0XSkpKwogIHlsYWIoIk51bWJlciBvZiBDbGlja3MiKSsKICBzY2FsZV9zaGFwZV9tYW51YWwobmFtZT0iIix2YWx1ZXMgPSBjKDE3LDE2KSkgKwogIHNjYWxlX2NvbG9yX21hbnVhbChuYW1lPSIiLHZhbHVlcyA9IGMoIjEiPSIjOTBCRTZEIiwiMCI9IiNGOTQxNDQiKSkrCiAgdGhlbWVfY2xhc3NpYygpKwogIHRoZW1lKGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZT0gc2l6ZV9iaWcpLAogICAgICAgYXhpcy50ZXh0PWVsZW1lbnRfdGV4dChzaXplPXNpemVfc21hbGwpLAogICAgICAgbGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSsKICB5bGltKDEwLDUwKQojKyAgZ3VpZGVzKHNoYXBlID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMpKSkKCiMgSnVzdGlmaWNhdGlvbiB0byByZWR1Y2UgcmFuZ2UgdG8gMTAtNTAKc3VtKGJldHdlZW4oZGF0YVRyaWFsX1RTUF9jbGlja3Mkbl9jbGlja3MsMTAsNTApKS9sZW5ndGgoZGF0YVRyaWFsX1RTUF9jbGlja3Mkbl9jbGlja3MpCgoKcGxvCmdnc2F2ZShwYXN0ZTAoZm9sZGVyT3V0X2ZpZ3VyZXMsIi9JQ19UU1BfbmNsaWNrcy5wZGYiKSxwbG8sd2lkdGggPSA2LGhlaWdodCA9Nix1bml0cz0iaW4iKQpgYGAKCiMjIyMjIEFuZCBzYXRpc2ZpYWJpbGl0eQoKYGBge3J9CiNMb2dpc3RpYyBSZWdyZXNzaW9uIGZvciBJbi9PdXQgUGhhc2UgdHJhbnNpdGlvbgpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9UU1BfY2xpY2tzCgojbG9naXN0aWMgd2l0aCByYW5kb20gZWZmZWN0cyAoaW50ZXJjZXB0KQojIFRUVE9ETwpyYW5kb21JbnRlcmNlcHQgPSBicm0yKG5fY2xpY2tzIH4gSUNleHBvc3QgKyBzb2wgKyBJQ2V4cG9zdDpzb2wgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwLCBpdGVyID0gaXRlcnNfaGlnaCkKCnRhYmxlTmFtZT0idHNwX2NsaWNrc18wM19yQiIKc2F2ZV9zdW1tYXJpc2VfbW9kZWwocmFuZG9tSW50ZXJjZXB0LCB0YWJsZU5hbWUpCmBgYAoKYGBge3J9CiNMb2dpc3RpYyBSZWdyZXNzaW9uIGZvciBJbi9PdXQgUGhhc2UgdHJhbnNpdGlvbgpkYXRhSW5wdXQ9IGRhdGFUcmlhbF9UU1BfY2xpY2tzCgojbG9naXN0aWMgd2l0aCByYW5kb20gZWZmZWN0cyAoaW50ZXJjZXB0KQojIFRUVE9ETwpyYW5kb21JbnRlcmNlcHQgPSBicm0yKG5fY2xpY2tzIH4gSUNleHBvc3QgKyBzb2wgKyAoMXxwSUQpLAogICAgICAgICAgICAgICAgICAgICAgZGF0YT1kYXRhSW5wdXQsIAogICAgICAgICAgICAgICAgICAgICAgY2hhaW5zPWNoYWluc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgY29yZXMgPSBjb3Jlc19icm1zLAogICAgICAgICAgICAgICAgICAgICAgc2VlZD1zZWVkX2JybXMsIHJlZnJlc2ggPSAwLCBpdGVyID0gaXRlcnNfaGlnaCkKCnRhYmxlTmFtZT0idHNwX2NsaWNrc18wM19yQyIKc2F2ZV9zdW1tYXJpc2VfbW9kZWwocmFuZG9tSW50ZXJjZXB0LCB0YWJsZU5hbWUpCmBgYAoKYGBge3J9CnBwICA9IHBsb3QoY29uZGl0aW9uYWxfZWZmZWN0cyhhbGxNb2RlbHNbWyJ0c3BfY2xpY2tzXzAzX3JDIl1dKSwgcGxvdCA9IFRSVUUsIGFzayA9IEZBTFNFKQpgYGAKCiMjIyMgTnVtYmVyIG9mIHdpdG5lc3NlcwoKT25seSBTYXRpc2ZpYWJsZSBpbnN0YW5jZXM6CgpgYGB7cn0KZGF0YUlucHV0PSBkYXRhVHJpYWxfVFNQX2NsaWNrcyAlPiUgZmlsdGVyKHNvbD09MSkKCmRhdGFJbnB1dCRuU29sdXRpb25zX2xvZyA9IGxvZyhkYXRhSW5wdXQkblNvbHV0aW9ucykKI2xvZ2lzdGljIHdpdGggcmFuZG9tIGVmZmVjdHMgKGludGVyY2VwdCkKIyBUVFRPRE8KcmFuZG9tSW50ZXJjZXB0ID0gYnJtMihuX2NsaWNrcyB+IG5Tb2x1dGlvbnNfbG9nICsgKDF8cElEKSwKICAgICAgICAgICAgICAgICAgICAgIGRhdGE9ZGF0YUlucHV0LCAKICAgICAgICAgICAgICAgICAgICAgIGNoYWlucz1jaGFpbnNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIGNvcmVzID0gY29yZXNfYnJtcywKICAgICAgICAgICAgICAgICAgICAgIHNlZWQ9c2VlZF9icm1zLCByZWZyZXNoID0gMCwgaXRlciA9IGl0ZXJzX2hpZ2gpCgp0YWJsZU5hbWU9InRzcF9jbGlja3NfMDRfckIiCnNhdmVfc3VtbWFyaXNlX21vZGVsKHJhbmRvbUludGVyY2VwdCwgdGFibGVOYW1lKQpgYGAKCmBgYHtyfQojZGF0YUlucHV0ID0gZGF0YVRyaWFsX1NBVF9jbGlja3MKIyBTdW1tYXJpc2UgdGhlIGRhdGEgdG8gcGxvdAptZWFuX25jbGlja3MgPSBkYXRhSW5wdXQgJT4lIAogIGdyb3VwX2J5KGluc3RhbmNlTnVtYmVyLCBzb2wsIElDZXhwb3N0LCBwaGFzZVQsIG5Tb2x1dGlvbnNfbG9nKSAlPiUgCiAgc3VtbWFyaXNlKG5fY2xpY2tzID0gbWVkaWFuKG5fY2xpY2tzKSkKCm1vZGVsX25zb2wgPSBhbGxNb2RlbHNbWyJ0c3BfY2xpY2tzXzA0X3JCIl1dCnBwICA9IHBsb3QoY29uZGl0aW9uYWxfZWZmZWN0cyhtb2RlbF9uc29sKSwgcGxvdCA9IEZBTFNFLCBhc2sgPSBGQUxTRSkKCnBwJG5Tb2x1dGlvbnNfbG9nICsKICAgZ2VvbV9wb2ludChkYXRhPW1lYW5fbmNsaWNrcywgYWVzKHggPSBuU29sdXRpb25zX2xvZywgeSA9bl9jbGlja3MpLGluaGVyaXQuYWVzID0gRkFMU0UpCmBgYAoKYGBge3J9CiMgSW1wcm92aW5nIHRoZSBwbG90CiMgSW1wcm92aW5nIHRoZSBwbG90CnNpemVfYmlnID0gMjAKc2l6ZV9zbWFsbCA9IDE2CnNpemVfc3MgPSAxMApzaXplX3hzID0gNwoKcHBfcGxvdCA9IHBwJG5Tb2x1dGlvbnMKcHBfcGxvdCRsYXllcnNbWzFdXSRnZW9tX3BhcmFtcyRzZSA9IEZBTFNFCnBwX3Bsb3QkbGF5ZXJzW1sxXV0kYWVzX3BhcmFtcyRjb2xvdXI9IiM1Nzc1OTAiCgpwcF9wbG90JGxheWVycyA8LSBjKGdlb21faml0dGVyKGRhdGE9ZGF0YUlucHV0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBuU29sdXRpb25zX2xvZywgeSA9IG5fY2xpY2tzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpKSwgc2l6ZT0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFscGhhID0gMC4zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaGVyaXQuYWVzID0gRkFMU0Usd2lkdGg9MC4yLGhlaWdodCA9MC4yKSwKICAgICAgICAgICAgICAgICAgICAgICAgZ2VvbV9wb2ludChkYXRhPW1lYW5fbmNsaWNrcywgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWVzKHggPSBuU29sdXRpb25zX2xvZywgeSA9IG5fY2xpY2tzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2w9YXMuZmFjdG9yKHNvbCksIHNoYXBlPWFzLmZhY3RvcihwaGFzZVQpKSwgc2l6ZT00LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluaGVyaXQuYWVzID0gRkFMU0UpLAogICAgICAgICAgICAgICAgICAgICAgICAgcHBfcGxvdCRsYXllcnMpCgpwbG8gPSBwcF9wbG90ICsKICB4bGFiKCJOdW1iZXIgb2YgU29sdXRpb24gV2l0bmVzc2VzIikrCiAgeWxhYigiTnVtYmVyIG9mIENsaWNrcyIpKwogIHNjYWxlX3NoYXBlX21hbnVhbChuYW1lPSIiLHZhbHVlcyA9IGMoMTcsMTYpKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKG5hbWU9IiIsdmFsdWVzID0gYygiMSI9IiM5MEJFNkQiLCIwIj0iI0Y5NDE0NCIpKSsKICB0aGVtZV9jbGFzc2ljKCkrCiAgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplPSBzaXplX2JpZyksCiAgICAgICBheGlzLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9c2l6ZV9zbWFsbCksCiAgICAgICBsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpKwogIGd1aWRlcyhzaGFwZSA9IGd1aWRlX2xlZ2VuZChvdmVycmlkZS5hZXMgPSBsaXN0KHNpemUgPSAzKSkpKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKGxvZygxKSxsb2coMTApLGxvZygxMDApLGxvZygxMDAwKSxsb2coMTAwMDApKSwKICAgICAgICAgICAgICAgICAgIGxpbWl0cyA9YygwLE5BKSxsYWJlbHMgPSBjKCIxIiwiMTAiLCIxMDAiLCIxMDAwIiwiMTAwMDAiKSApKwogIHlsaW0oMTAsNTApCgpwbG8KCmdnc2F2ZShwYXN0ZTAoZm9sZGVyT3V0X2ZpZ3VyZXMsIi9Od2l0X1RTUF9uY2xpY2tzLnBkZiIpLAogICAgICAgcGxvLHdpZHRoID0gNixoZWlnaHQgPTYsdW5pdHM9ImluIikKYGBgCgojIFNhdmUgTW9kZWxzCgpgYGB7cn0KI3NhdmVSRFMoYWxsTW9kZWxzLGZpbGUucGF0aChmb2xkZXJPdXQsIklDeDNfbW9kZWxzLlJEYXRhIikpCgpgYGAKCiMgU2Vzc2lvbiBJbmZvCgpgYGB7cn0Kc2Vzc2lvbkluZm8oKQpgYGAKCg==